Skip to content

UI Node Gradients #18139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 138 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 135 commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
8eb3c64
Added shader, plugin and components for linear gradients
ickshonpe Feb 16, 2025
e1208e3
Merge branch 'main' into Gradient
ickshonpe Feb 26, 2025
8b9dd40
Added coordinates computation and fixed errors in renderer
ickshonpe Feb 26, 2025
2494464
Added "linear_gradients" example
ickshonpe Feb 26, 2025
ca61384
Fixed shader panics
ickshonpe Feb 26, 2025
bd6cf34
improved example
ickshonpe Feb 26, 2025
3d2d9bc
shader gradient function working
ickshonpe Mar 1, 2025
f0d8192
fixed interpolation
ickshonpe Mar 3, 2025
6abaccd
Merge branch 'main' into Gradient
ickshonpe Mar 3, 2025
8bc0fc0
Extract stops into a seperate buffer
ickshonpe Mar 3, 2025
754c708
Gradients rendering correctly
ickshonpe Mar 3, 2025
c0638ed
Resolve color stops during extraction.
ickshonpe Mar 3, 2025
e52ded5
Clean up. Fixed `ColorStop` From<Color>` impl so the points are `Val:…
ickshonpe Mar 3, 2025
d71ccbe
Enabled linear gradient border rendering.
ickshonpe Mar 3, 2025
3c90098
Push extra stops if end stops don't cover the whole node.
ickshonpe Mar 3, 2025
16f1557
Build templated pages
ickshonpe Mar 3, 2025
c638b7b
Fixed srgb colour interpolation
ickshonpe Mar 3, 2025
10612be
Use `sin` and `cos` from `bevy_math::ops`
ickshonpe Mar 3, 2025
c2faa36
Tweaks to the example
ickshonpe Mar 3, 2025
c0115ef
Import from core not std.
ickshonpe Mar 3, 2025
4a94077
changed `cos(-angle)` (`!= -angle.cos()`) to `-cos(self.angle)`
ickshonpe Mar 3, 2025
3aa90ac
animate the gradients
ickshonpe Mar 3, 2025
2c4d9e1
improved example
ickshonpe Mar 3, 2025
d79ba5a
Merge branch 'main' into linear-gradients
ickshonpe Mar 3, 2025
10c79b8
Changed example's color stops
ickshonpe Mar 3, 2025
44c1308
Tidy up example's layout
ickshonpe Mar 3, 2025
36c8ff1
Fixed draw order so gradients after background and borders
ickshonpe Mar 4, 2025
882b4a6
Clean up, fixed derives
ickshonpe Mar 4, 2025
b3858b8
Added doc comments
ickshonpe Mar 4, 2025
4df831a
Merge branch 'main' into linear-gradients
ickshonpe Mar 4, 2025
d5d1c6c
Merge branch 'main' into linear-gradients
ickshonpe Mar 4, 2025
c19dd75
Added radial gradient rendering.
ickshonpe Mar 4, 2025
12bdc5d
Added start and end fill flags to shader
ickshonpe Mar 4, 2025
5caa9e4
Added new Gradient and Radial Gradient API
ickshonpe Mar 4, 2025
ec75acc
Updated example, split `Gradient` into `GradientNode` and `GradientBo…
ickshonpe Mar 4, 2025
a1f4a18
added resolve function for `RelativePosition
ickshonpe Mar 4, 2025
c776256
Refactorings to support Conic and Radial gradients.
ickshonpe Mar 4, 2025
fe080bc
Changed third gradient in example to a rainbow
ickshonpe Mar 4, 2025
8c44f24
Stabilized color stop order by not reverse sorting.
ickshonpe Mar 4, 2025
f299b23
Removed angle field from ExtractedGradient
ickshonpe Mar 4, 2025
638abc2
Added basic color stop resolution for radial and conic gradients.
ickshonpe Mar 4, 2025
b3b7ac5
Merge branch 'main' into linear-gradients
ickshonpe Mar 4, 2025
c89e296
Fixed shader handle clash.
ickshonpe Mar 5, 2025
13902dd
Removed unused
ickshonpe Mar 5, 2025
02baf6b
applied clippy suggested fixes
ickshonpe Mar 5, 2025
cb595dc
clean up
ickshonpe Mar 5, 2025
b7b8a4f
Removed the automatically start and end stops.
ickshonpe Mar 5, 2025
ec44df2
Removed comments
ickshonpe Mar 5, 2025
0d79ca6
FIxed angular color stop interpolation.
ickshonpe Mar 5, 2025
575141d
Removed no longer needed automatic stops
ickshonpe Mar 5, 2025
6ccf489
Added `new` method to `ColorStop`
ickshonpe Mar 5, 2025
b6861f0
Added radial gradients example
ickshonpe Mar 5, 2025
85d621c
Fixed circular radial gradient geometry.
ickshonpe Mar 5, 2025
10833bf
Changed the `Val::resolve` method to always return always return a va…
ickshonpe Mar 5, 2025
1f2aafb
Merge branch 'val-physical-resolve' into linear-gradients
ickshonpe Mar 5, 2025
a295303
Refactor to remove use of logical coords in the stops resolution code.
ickshonpe Mar 5, 2025
018126d
Renamed `RelativePosition` to `RelativeVal`.
ickshonpe Mar 6, 2025
da25bb7
Removed unused import
ickshonpe Mar 6, 2025
748b682
Add `RelativeVal` and `RelativePosition` types. Fixed most of the bug…
ickshonpe Mar 6, 2025
a95cbcf
Added doc comments and helper functions
ickshonpe Mar 7, 2025
2e71282
More doc comments
ickshonpe Mar 7, 2025
06eb5e6
Comment corrections
ickshonpe Mar 7, 2025
15b2248
Renamed `GradientNode` to `BackGroundGradient` and `GradientBorder` t…
ickshonpe Mar 7, 2025
2106a99
`BackgroundGradient` and `BorderGradient` now take a vector of gradie…
ickshonpe Mar 7, 2025
48e3999
Added `overlaid_gradients` example
ickshonpe Mar 7, 2025
2440525
build-templated-pages
ickshonpe Mar 7, 2025
9751672
use `try_insert_batch` instead of `insert_or_spawn_batch`
ickshonpe Mar 7, 2025
a1d0e1e
Fixed markdown links
ickshonpe Mar 7, 2025
027f53b
Clippy fixes
ickshonpe Mar 7, 2025
ed5e8a5
Removed unnecesary format!s
ickshonpe Mar 7, 2025
f3620df
Fixed spelling errors in comments
ickshonpe Mar 7, 2025
5e334cc
Implemented overlaid_gradients example
ickshonpe Mar 7, 2025
64b78a3
improved example
ickshonpe Mar 7, 2025
8065421
Removed useless conversions
ickshonpe Mar 7, 2025
22d1064
Fixed spelling mistake
ickshonpe Mar 7, 2025
953da20
Changed default for `RelativeVal` to `Val::ZERO`
ickshonpe Mar 7, 2025
58c8b52
Merge branch 'main' into linear-gradients
ickshonpe Mar 7, 2025
dd44d8b
More doc comments
ickshonpe Mar 7, 2025
33540bf
removed scaling of length in extracted_gradients
ickshonpe Mar 8, 2025
84473b9
Renamed `overlaid_gradients` example to `stacked_gradients`
ickshonpe Mar 8, 2025
546907b
More doc comments
ickshonpe Mar 8, 2025
42033e4
Removed `RelativeVal` replaced with new `NodeAnchor` API.
ickshonpe Mar 8, 2025
624f2f3
Updated examples for relative position refactor
ickshonpe Mar 8, 2025
d64ffb0
Merge branch 'main' into linear-gradients
ickshonpe Mar 8, 2025
80d355a
added serialize derive for NodeAnchor
ickshonpe Mar 8, 2025
ada7195
cargo run -p build-templated-pages -- update examples
ickshonpe Mar 8, 2025
6a809ba
Merge branch 'main' into linear-gradients
ickshonpe Mar 8, 2025
22280c1
Removed `NodeAnchor`
ickshonpe Mar 8, 2025
acaa984
Changed color stop constructors to take Into<Color> instead of Color
ickshonpe Mar 8, 2025
4779ad9
Cleaned up radial_gradients example
ickshonpe Mar 8, 2025
b3b7af7
far_side function used min and returned the close_side, fixed by usin…
ickshonpe Mar 8, 2025
6c92af0
Fixed elliptical gradients
ickshonpe Mar 8, 2025
b414e0c
unswitched conic coords, set radial ratio to 1 in degenerate case
ickshonpe Mar 8, 2025
3d029ba
Added a few more comments.
ickshonpe Mar 9, 2025
a7a104f
Merge branch 'main' into linear-gradients
ickshonpe Mar 9, 2025
5cbdb59
removed single-element-loop
ickshonpe Mar 9, 2025
9cc543b
fixed syntax error in radial gradients example
ickshonpe Mar 9, 2025
7ea494a
Merge branch 'main' into linear-gradients
ickshonpe Mar 9, 2025
4688682
Merge branch 'main' into linear-gradients
ickshonpe Mar 9, 2025
c94e925
Added color stop hints
ickshonpe Mar 10, 2025
c9c0a78
Fixed spelling
ickshonpe Mar 10, 2025
d9d446e
Merge branch 'main' into linear-gradients
ickshonpe Mar 10, 2025
1a5c7db
Merge branch 'main' into linear-gradients
ickshonpe Mar 11, 2025
1b8778d
import UI node sdf functions from `ui.wgsl`
ickshonpe Mar 11, 2025
862d412
Added `gradients` module
ickshonpe Mar 11, 2025
de2ddaf
Refactored ui.wgsl so it can be used imported
ickshonpe Mar 11, 2025
2059a9b
Fixed using wrong color as argument in ui.wgsl
ickshonpe Mar 11, 2025
0b69362
Moved gradient types to `gradients` module
ickshonpe Mar 11, 2025
ae82ef2
extracted color stops computation into a function
ickshonpe Mar 11, 2025
4893650
Fix linear gradient start point when clipped
ickshonpe Mar 11, 2025
013f88d
Refactor the Gradient enum to use types for each variant.
ickshonpe Mar 11, 2025
25ee522
Merge branch 'main' into linear-gradients
ickshonpe Mar 11, 2025
7fd4daf
Replace conditional corner index computation with a branchless mapping
ickshonpe Mar 12, 2025
12368db
Replaced Vec2 -> [f32; 2] conversion.
ickshonpe Mar 12, 2025
8ae8c7b
Another `Position` rewrite.
ickshonpe Mar 12, 2025
370e786
Renamed `PositionX` to `AtX`
ickshonpe Mar 12, 2025
51a56a8
fixed example
ickshonpe Mar 12, 2025
1ed8345
changed import from std to core
ickshonpe Mar 12, 2025
03303b9
changed start boundary condition to `<`
ickshonpe Mar 12, 2025
8e899c2
More helper functions
ickshonpe Mar 12, 2025
637befd
Merge branch 'main' into linear-gradients
ickshonpe Mar 12, 2025
bea95af
Fixed sort key for gradient plugin
ickshonpe Mar 12, 2025
09d4057
Example cleanup
ickshonpe Mar 12, 2025
b5673cf
Removed useless conversion
ickshonpe Mar 12, 2025
acc8fb2
Another new Position API, anchors now Vec2
ickshonpe Mar 13, 2025
6e9f773
Updated doc comments
ickshonpe Mar 13, 2025
ca182aa
Doc comments
ickshonpe Mar 13, 2025
cfb5862
Renamed `ColorStop::hint` and `AngularColorStop::hint` to `with_hint`…
ickshonpe Mar 13, 2025
5cfb2a0
Merge branch 'main' into linear-gradients
ickshonpe Mar 13, 2025
9be58e8
Merge branch 'main' into linear-gradients
ickshonpe Mar 13, 2025
b10b6e2
Fixed discontinuities at angled sharp stops
ickshonpe Mar 14, 2025
e650fb4
Merge branch 'linear-gradients' of https://github.com/ickshonpe/bevy …
ickshonpe Mar 14, 2025
680091d
Merge branch 'main' into linear-gradients
ickshonpe Mar 17, 2025
54a0f9b
Merge branch 'main' into linear-gradients
ickshonpe Mar 18, 2025
0db6bfe
Merge branch 'main' into linear-gradients
ickshonpe Mar 20, 2025
90688ab
Removed unnecessary clone() from example
ickshonpe Mar 20, 2025
5a02de9
Merge branch 'main' into linear-gradients
ickshonpe Mar 22, 2025
e501e3a
Merge branch 'main' into linear-gradients
ickshonpe Mar 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3398,6 +3398,39 @@ description = "An example for CSS Grid layout"
category = "UI (User Interface)"
wasm = true

[[example]]
name = "gradients"
path = "examples/ui/gradients.rs"
doc-scrape-examples = true

[package.metadata.example.gradients]
name = "Gradients"
description = "An example demonstrating gradients"
category = "UI (User Interface)"
wasm = true

[[example]]
name = "stacked_gradients"
path = "examples/ui/stacked_gradients.rs"
doc-scrape-examples = true

[package.metadata.example.stacked_gradients]
name = "Stacked Gradients"
description = "An example demonstrating stacked gradients"
category = "UI (User Interface)"
wasm = true

[[example]]
name = "radial_gradients"
path = "examples/ui/radial_gradients.rs"
doc-scrape-examples = true

[package.metadata.example.radial_gradients]
name = "Radial Gradients"
description = "An example demonstrating radial gradients"
category = "UI (User Interface)"
wasm = true

[[example]]
name = "scroll"
path = "examples/ui/scroll.rs"
Expand Down
242 changes: 216 additions & 26 deletions crates/bevy_ui/src/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bevy_math::Vec2;
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_utils::default;
use core::ops::{Div, DivAssign, Mul, MulAssign, Neg};
use thiserror::Error;

Expand Down Expand Up @@ -255,19 +256,23 @@ pub enum ValArithmeticError {
}

impl Val {
/// Resolves a [`Val`] from the given context values and returns this as an [`f32`].
/// The [`Val::Px`] value (if present), `parent_size` and `viewport_size` should all be in the same coordinate space.
/// Returns a [`ValArithmeticError::NonEvaluable`] if the [`Val`] is impossible to resolve into a concrete value.
/// Resolves this [`Val`] to a value in physical pixels from the given `scale_factor`, `physical_base_value`,
/// and `physical_target_size` context values.
///
/// **Note:** If a [`Val::Px`] is resolved, its inner value is returned unchanged.
pub fn resolve(self, parent_size: f32, viewport_size: Vec2) -> Result<f32, ValArithmeticError> {
/// Returns a [`ValArithmeticError::NonEvaluable`] if the [`Val`] is impossible to resolve into a concrete value.
pub fn resolve(
self,
scale_factor: f32,
physical_base_value: f32,
physical_target_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::Percent(value) => Ok(physical_base_value * value / 100.0),
Val::Px(value) => Ok(value * scale_factor),
Val::Vw(value) => Ok(physical_target_size.x * value / 100.0),
Val::Vh(value) => Ok(physical_target_size.y * value / 100.0),
Val::VMin(value) => Ok(physical_target_size.min_element() * value / 100.0),
Val::VMax(value) => Ok(physical_target_size.max_element() * value / 100.0),
Val::Auto => Err(ValArithmeticError::NonEvaluable),
}
}
Expand Down Expand Up @@ -678,6 +683,179 @@ impl Default for UiRect {
}
}

#[derive(Debug, Clone, Copy, PartialEq, Reflect)]
#[reflect(Default, Debug, PartialEq)]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
reflect(Serialize, Deserialize)
)]
/// Responsive position relative to a UI node.
pub struct Position {
/// Normalized anchor point
pub anchor: Vec2,
/// Responsive horizontal position relative to the anchor point
pub x: Val,
/// Responsive vertical position relative to the anchor point
pub y: Val,
}

impl Default for Position {
fn default() -> Self {
Self::CENTER
}
}

impl Position {
/// Position at the given normalized anchor point
pub const fn anchor(anchor: Vec2) -> Self {
Self {
anchor,
x: Val::ZERO,
y: Val::ZERO,
}
}

/// Position at the top-left corner
pub const TOP_LEFT: Self = Self::anchor(Vec2::new(-0.5, -0.5));

/// Position at the center of the left edge
pub const LEFT: Self = Self::anchor(Vec2::new(-0.5, 0.0));

/// Position at the bottom-left corner
pub const BOTTOM_LEFT: Self = Self::anchor(Vec2::new(-0.5, 0.5));

/// Position at the center of the top edge
pub const TOP: Self = Self::anchor(Vec2::new(0.0, -0.5));

/// Position at the center of the element
pub const CENTER: Self = Self::anchor(Vec2::new(0.0, 0.0));

/// Position at the center of the bottom edge
pub const BOTTOM: Self = Self::anchor(Vec2::new(0.0, 0.5));

/// Position at the top-right corner
pub const TOP_RIGHT: Self = Self::anchor(Vec2::new(0.5, -0.5));

/// Position at the center of the right edge
pub const RIGHT: Self = Self::anchor(Vec2::new(0.5, 0.0));

/// Position at the bottom-right corner
pub const BOTTOM_RIGHT: Self = Self::anchor(Vec2::new(0.5, 0.5));

/// Create a new position
pub const fn new(anchor: Vec2, x: Val, y: Val) -> Self {
Self { anchor, x, y }
}

/// Creates a position from self with the given `x` and `y` coordinates
pub const fn at(self, x: Val, y: Val) -> Self {
Self { x, y, ..self }
}

/// Creates a position from self with the given `x` coordinate
pub const fn at_x(self, x: Val) -> Self {
Self { x, ..self }
}

/// Creates a position from self with the given `y` coordinate
pub const fn at_y(self, y: Val) -> Self {
Self { y, ..self }
}

/// Creates a position in logical pixels from self with the given `x` and `y` coordinates
pub const fn at_px(self, x: f32, y: f32) -> Self {
self.at(Val::Px(x), Val::Px(y))
}

/// Creates a percentage position from self with the given `x` and `y` coordinates
pub const fn at_percent(self, x: f32, y: f32) -> Self {
self.at(Val::Percent(x), Val::Percent(y))
}

/// Creates a position from self with the given `anchor` point
pub const fn with_anchor(self, anchor: Vec2) -> Self {
Self { anchor, ..self }
}

/// Position relative to the top-left corner
pub const fn top_left(x: Val, y: Val) -> Self {
Self::TOP_LEFT.at(x, y)
}

/// Position relative to the left edge
pub const fn left(x: Val, y: Val) -> Self {
Self::LEFT.at(x, y)
}

/// Position relative to the bottom-left corner
pub const fn bottom_left(x: Val, y: Val) -> Self {
Self::BOTTOM_LEFT.at(x, y)
}

/// Position relative to the top edge
pub const fn top(x: Val, y: Val) -> Self {
Self::TOP.at(x, y)
}

/// Position relative to the center
pub const fn center(x: Val, y: Val) -> Self {
Self::CENTER.at(x, y)
}

/// Position relative to the bottom edge
pub const fn bottom(x: Val, y: Val) -> Self {
Self::BOTTOM.at(x, y)
}

/// Position relative to the top-right corner
pub const fn top_right(x: Val, y: Val) -> Self {
Self::TOP_RIGHT.at(x, y)
}

/// Position relative to the right edge
pub const fn right(x: Val, y: Val) -> Self {
Self::RIGHT.at(x, y)
}

/// Position relative to the bottom-right corner
pub const fn bottom_right(x: Val, y: Val) -> Self {
Self::BOTTOM_RIGHT.at(x, y)
}

/// Resolves the `Position` into physical coordinates.
pub fn resolve(
self,
scale_factor: f32,
physical_size: Vec2,
physical_target_size: Vec2,
) -> Vec2 {
let d = self.anchor.map(|p| if 0. < p { -1. } else { 1. });

physical_size * self.anchor
+ d * Vec2::new(
self.x
.resolve(scale_factor, physical_size.x, physical_target_size)
.unwrap_or(0.),
self.y
.resolve(scale_factor, physical_size.y, physical_target_size)
.unwrap_or(0.),
)
}
}

impl From<Val> for Position {
fn from(x: Val) -> Self {
Self { x, ..default() }
}
}

impl From<(Val, Val)> for Position {
fn from((x, y): (Val, Val)) -> Self {
Self { x, y, ..default() }
}
}

#[cfg(test)]
mod tests {
use crate::geometry::*;
Expand All @@ -687,7 +865,7 @@ mod tests {
fn val_evaluate() {
let size = 250.;
let viewport_size = vec2(1000., 500.);
let result = Val::Percent(80.).resolve(size, viewport_size).unwrap();
let result = Val::Percent(80.).resolve(1., size, viewport_size).unwrap();

assert_eq!(result, size * 0.8);
}
Expand All @@ -696,7 +874,7 @@ mod tests {
fn val_resolve_px() {
let size = 250.;
let viewport_size = vec2(1000., 500.);
let result = Val::Px(10.).resolve(size, viewport_size).unwrap();
let result = Val::Px(10.).resolve(1., size, viewport_size).unwrap();

assert_eq!(result, 10.);
}
Expand All @@ -709,33 +887,45 @@ mod tests {
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)
Val::Vw(value).resolve(1., size, viewport_size),
Val::Vh(value).resolve(1., size, viewport_size)
);
assert_eq!(
Val::VMin(value).resolve(size, viewport_size),
Val::VMax(value).resolve(size, viewport_size)
Val::VMin(value).resolve(1., size, viewport_size),
Val::VMax(value).resolve(1., size, viewport_size)
);
assert_eq!(
Val::VMin(value).resolve(size, viewport_size),
Val::Vw(value).resolve(size, viewport_size)
Val::VMin(value).resolve(1., size, viewport_size),
Val::Vw(value).resolve(1., 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.);
assert_eq!(
Val::Vw(100.).resolve(1., size, viewport_size).unwrap(),
1000.
);
assert_eq!(
Val::Vh(100.).resolve(1., size, viewport_size).unwrap(),
500.
);
assert_eq!(Val::Vw(60.).resolve(1., size, viewport_size).unwrap(), 600.);
assert_eq!(Val::Vh(40.).resolve(1., size, viewport_size).unwrap(), 200.);
assert_eq!(
Val::VMin(50.).resolve(1., size, viewport_size).unwrap(),
250.
);
assert_eq!(
Val::VMax(75.).resolve(1., size, viewport_size).unwrap(),
750.
);
}

#[test]
fn val_auto_is_non_evaluable() {
let size = 250.;
let viewport_size = vec2(1000., 500.);
let resolve_auto = Val::Auto.resolve(size, viewport_size);
let resolve_auto = Val::Auto.resolve(1., size, viewport_size);

assert_eq!(resolve_auto, Err(ValArithmeticError::NonEvaluable));
}
Expand Down
Loading
Loading