Skip to content

Commit 60c6934

Browse files
author
KDecay
committed
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!
1 parent ee3368b commit 60c6934

File tree

1 file changed

+188
-12
lines changed

1 file changed

+188
-12
lines changed

crates/bevy_ui/src/geometry.rs

Lines changed: 188 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,179 @@ use bevy_math::Vec2;
22
use bevy_reflect::Reflect;
33
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
44

5-
/// A rect, as defined by its "side" locations
5+
/// A type which is commonly used to define positions, margins, paddings and borders.
6+
///
7+
/// # Examples
8+
///
9+
/// ## Position
10+
///
11+
/// A position is used to determine where to place a UI element.
12+
///
13+
/// ```
14+
/// # use bevy_ui::{UiRect, Val};
15+
/// # use bevy_utils::default;
16+
/// #
17+
/// let position = UiRect {
18+
/// left: Val::Px(100.0),
19+
/// top: Val::Px(50.0),
20+
/// ..default()
21+
/// };
22+
/// ```
23+
///
24+
/// If you define opposite sides of the position, the size of the UI element will automatically be calculated
25+
/// if not explicitly specified. This means that if you have a [`Size`] that uses [`Val::Undefined`](crate::Val::Undefined)
26+
/// as a width and height, the size would be determined by the window size and the values specified in the position.
27+
///
28+
/// ```
29+
/// # use bevy_ui::{UiRect, Val};
30+
/// #
31+
/// let position = UiRect {
32+
/// left: Val::Px(100.0),
33+
/// right: Val::Px(200.0),
34+
/// top: Val::Px(300.0),
35+
/// bottom: Val::Px(400.0),
36+
/// };
37+
/// ```
38+
///
39+
/// To determine the width of the UI element you have to take the width of the window and subtract it by the
40+
/// left and right values of the position. To determine the height of the UI element you have to take the height
41+
/// of the window and subtract it by the top and bottom values of the position. If we had a window with a width
42+
/// and height of 1000px, the UI element declared above would have a width of 700px and a height of 300px.
43+
///
44+
/// ```
45+
/// // Size of the window
46+
/// let window_width = 1000.0;
47+
/// let window_height = 1000.0;
48+
///
49+
/// // Values of the position
50+
/// let left = 100.0;
51+
/// let right = 200.0;
52+
/// let top = 300.0;
53+
/// let bottom = 400.0;
54+
///
55+
/// // Calculation to get the size of the UI element
56+
/// let ui_element_width = window_width - left - right;
57+
/// let ui_element_height = window_height - top - bottom;
58+
///
59+
/// assert_eq!(ui_element_width, 700.0);
60+
/// assert_eq!(ui_element_height, 300.0);
61+
/// ```
62+
///
63+
/// If you define a [`Size`] and also all four sides of the position, the top and left values of the position
64+
/// are used to determine where to place the UI element. The size will not be calculated using the bottom and
65+
/// right values of the position because the size of the UI element is already explicitly specified.
66+
///
67+
/// ```
68+
/// # use bevy_ui::{UiRect, Size, Val, Style};
69+
/// # use bevy_utils::default;
70+
/// #
71+
/// let style = Style {
72+
/// position: UiRect { // Defining all four sides
73+
/// left: Val::Px(100.0),
74+
/// right: Val::Px(200.0),
75+
/// top: Val::Px(300.0),
76+
/// bottom: Val::Px(400.0),
77+
/// },
78+
/// size: Size::new(Val::Percent(100.0), Val::Percent(50.0)), // but also explicitly specifying a size
79+
/// ..default()
80+
/// };
81+
/// ```
82+
///
83+
/// ## Margin
84+
///
85+
/// A margin is used to create space around UI elements, outside of any defined borders.
86+
///
87+
/// ```
88+
/// # use bevy_ui::{UiRect, Val};
89+
/// #
90+
/// let margin = UiRect::all(Val::Auto); // Centers the UI element
91+
/// ```
92+
///
93+
/// ## Padding
94+
///
95+
/// A padding is used to create space around UI elements, inside of any defined borders.
96+
///
97+
/// ```
98+
/// # use bevy_ui::{UiRect, Val};
99+
/// #
100+
/// let padding = UiRect {
101+
/// left: Val::Px(10.0),
102+
/// right: Val::Px(20.0),
103+
/// top: Val::Px(30.0),
104+
/// bottom: Val::Px(40.0),
105+
/// };
106+
/// ```
107+
///
108+
/// ## Borders
109+
///
110+
/// A border is used to define the width of the border of a UI element.
111+
///
112+
/// ```
113+
/// # use bevy_ui::{UiRect, Val};
114+
/// #
115+
/// let border = UiRect {
116+
/// left: Val::Px(10.0),
117+
/// right: Val::Px(20.0),
118+
/// top: Val::Px(30.0),
119+
/// bottom: Val::Px(40.0),
120+
/// };
121+
/// ```
6122
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
7123
#[reflect(PartialEq)]
8124
pub struct UiRect<T: Reflect + PartialEq> {
125+
/// The value corresponding to the left side of the UI rect.
9126
pub left: T,
127+
/// The value corresponding to the right side of the UI rect.
10128
pub right: T,
129+
/// The value corresponding to the top side of the UI rect.
11130
pub top: T,
131+
/// The value corresponding to the bottom side of the UI rect.
12132
pub bottom: T,
13133
}
14134

15135
impl<T: Reflect + PartialEq> UiRect<T> {
136+
/// Creates a new [`UiRect`] from the values specified.
137+
///
138+
/// # Example
139+
///
140+
/// ```
141+
/// # use bevy_ui::{UiRect, Val};
142+
/// #
143+
/// let ui_rect = UiRect::new(
144+
/// Val::Px(10.0),
145+
/// Val::Px(20.0),
146+
/// Val::Px(30.0),
147+
/// Val::Px(40.0),
148+
/// );
149+
///
150+
/// assert_eq!(ui_rect.left, Val::Px(10.0));
151+
/// assert_eq!(ui_rect.right, Val::Px(20.0));
152+
/// assert_eq!(ui_rect.top, Val::Px(30.0));
153+
/// assert_eq!(ui_rect.bottom, Val::Px(40.0));
154+
/// ```
155+
pub fn new(left: T, right: T, top: T, bottom: T) -> Self {
156+
UiRect {
157+
left,
158+
right,
159+
top,
160+
bottom,
161+
}
162+
}
163+
164+
/// Creates a new [`UiRect`] where all sides have the same value.
165+
///
166+
/// # Example
167+
///
168+
/// ```
169+
/// # use bevy_ui::{UiRect, Val};
170+
/// #
171+
/// let ui_rect = UiRect::all(Val::Px(10.0));
172+
///
173+
/// assert_eq!(ui_rect.left, Val::Px(10.0));
174+
/// assert_eq!(ui_rect.right, Val::Px(10.0));
175+
/// assert_eq!(ui_rect.top, Val::Px(10.0));
176+
/// assert_eq!(ui_rect.bottom, Val::Px(10.0));
177+
/// ```
16178
pub fn all(value: T) -> Self
17179
where
18180
T: Clone,
@@ -37,15 +199,31 @@ impl<T: Default + Reflect + PartialEq> Default for UiRect<T> {
37199
}
38200
}
39201

40-
/// A two dimensional "size" as defined by a width and height
202+
/// A 2-dimensional area defined by a width and height.
203+
///
204+
/// It is commonly used to define the size of a text or UI element.
41205
#[derive(Copy, Clone, PartialEq, Debug, Reflect)]
42206
#[reflect(PartialEq)]
43207
pub struct Size<T: Reflect + PartialEq = f32> {
208+
/// The width of the 2-dimensional area.
44209
pub width: T,
210+
/// The height of the 2-dimensional area.
45211
pub height: T,
46212
}
47213

48214
impl<T: Reflect + PartialEq> Size<T> {
215+
/// Creates a new [`Size`] from a width and a height.
216+
///
217+
/// # Example
218+
///
219+
/// ```
220+
/// # use bevy_ui::{Size, Val};
221+
/// #
222+
/// let size = Size::new(Val::Px(100.0), Val::Px(200.0));
223+
///
224+
/// assert_eq!(size.width, Val::Px(100.0));
225+
/// assert_eq!(size.height, Val::Px(200.0));
226+
/// ```
49227
pub fn new(width: T, height: T) -> Self {
50228
Size { width, height }
51229
}
@@ -162,23 +340,21 @@ mod tests {
162340

163341
#[test]
164342
fn size_ops() {
165-
type SizeF = Size<f32>;
166-
167343
assert_eq!(
168-
SizeF::new(10., 10.) + Vec2::new(10., 10.),
169-
SizeF::new(20., 20.)
344+
Size::new(10., 10.) + Vec2::new(10., 10.),
345+
Size::new(20., 20.)
170346
);
171347
assert_eq!(
172-
SizeF::new(20., 20.) - Vec2::new(10., 10.),
173-
SizeF::new(10., 10.)
348+
Size::new(20., 20.) - Vec2::new(10., 10.),
349+
Size::new(10., 10.)
174350
);
175-
assert_eq!(SizeF::new(10., 10.) * 2., SizeF::new(20., 20.));
176-
assert_eq!(SizeF::new(20., 20.) / 2., SizeF::new(10., 10.));
351+
assert_eq!(Size::new(10., 10.) * 2., Size::new(20., 20.));
352+
assert_eq!(Size::new(20., 20.) / 2., Size::new(10., 10.));
177353

178-
let mut size = SizeF::new(10., 10.);
354+
let mut size = Size::new(10., 10.);
179355

180356
size += Vec2::new(10., 10.);
181357

182-
assert_eq!(size, SizeF::new(20., 20.));
358+
assert_eq!(size, Size::new(20., 20.));
183359
}
184360
}

0 commit comments

Comments
 (0)