1//! The GPUI geometry module is a collection of types and traits that
2//! can be used to describe common units, concepts, and the relationships
3//! between them.
4
5use core::fmt::Debug;
6use derive_more::{Add, AddAssign, Div, DivAssign, Mul, Neg, Sub, SubAssign};
7use refineable::Refineable;
8use serde_derive::{Deserialize, Serialize};
9use std::{
10 cmp::{self, PartialOrd},
11 fmt,
12 hash::Hash,
13 ops::{Add, Div, Mul, MulAssign, Sub},
14};
15
16use crate::{AppContext, DisplayId};
17
18/// An axis along which a measurement can be made.
19#[derive(Copy, Clone, PartialEq, Eq, Debug)]
20pub enum Axis {
21 /// The y axis, or up and down
22 Vertical,
23 /// The x axis, or left and right
24 Horizontal,
25}
26
27impl Axis {
28 /// Swap this axis to the opposite axis.
29 pub fn invert(self) -> Self {
30 match self {
31 Axis::Vertical => Axis::Horizontal,
32 Axis::Horizontal => Axis::Vertical,
33 }
34 }
35}
36
37/// A trait for accessing the given unit along a certain axis.
38pub trait Along {
39 /// The unit associated with this type
40 type Unit;
41
42 /// Returns the unit along the given axis.
43 fn along(&self, axis: Axis) -> Self::Unit;
44
45 /// Applies the given function to the unit along the given axis and returns a new value.
46 fn apply_along(&self, axis: Axis, f: impl FnOnce(Self::Unit) -> Self::Unit) -> Self;
47}
48
49/// Describes a location in a 2D cartesian coordinate space.
50///
51/// It holds two public fields, `x` and `y`, which represent the coordinates in the space.
52/// The type `T` for the coordinates can be any type that implements `Default`, `Clone`, and `Debug`.
53///
54/// # Examples
55///
56/// ```
57/// # use zed::Point;
58/// let point = Point { x: 10, y: 20 };
59/// println!("{:?}", point); // Outputs: Point { x: 10, y: 20 }
60/// ```
61#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
62#[refineable(Debug)]
63#[repr(C)]
64pub struct Point<T: Default + Clone + Debug> {
65 /// The x coordinate of the point.
66 pub x: T,
67 /// The y coordinate of the point.
68 pub y: T,
69}
70
71/// Constructs a new `Point<T>` with the given x and y coordinates.
72///
73/// # Arguments
74///
75/// * `x` - The x coordinate of the point.
76/// * `y` - The y coordinate of the point.
77///
78/// # Returns
79///
80/// Returns a `Point<T>` with the specified coordinates.
81///
82/// # Examples
83///
84/// ```
85/// # use zed::Point;
86/// let p = point(10, 20);
87/// assert_eq!(p.x, 10);
88/// assert_eq!(p.y, 20);
89/// ```
90pub const fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
91 Point { x, y }
92}
93
94impl<T: Clone + Debug + Default> Point<T> {
95 /// Creates a new `Point` with the specified `x` and `y` coordinates.
96 ///
97 /// # Arguments
98 ///
99 /// * `x` - The horizontal coordinate of the point.
100 /// * `y` - The vertical coordinate of the point.
101 ///
102 /// # Examples
103 ///
104 /// ```
105 /// let p = Point::new(10, 20);
106 /// assert_eq!(p.x, 10);
107 /// assert_eq!(p.y, 20);
108 /// ```
109 pub const fn new(x: T, y: T) -> Self {
110 Self { x, y }
111 }
112
113 /// Transforms the point to a `Point<U>` by applying the given function to both coordinates.
114 ///
115 /// This method allows for converting a `Point<T>` to a `Point<U>` by specifying a closure
116 /// that defines how to convert between the two types. The closure is applied to both the `x`
117 /// and `y` coordinates, resulting in a new point of the desired type.
118 ///
119 /// # Arguments
120 ///
121 /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
122 ///
123 /// # Examples
124 ///
125 /// ```
126 /// # use zed::Point;
127 /// let p = Point { x: 3, y: 4 };
128 /// let p_float = p.map(|coord| coord as f32);
129 /// assert_eq!(p_float, Point { x: 3.0, y: 4.0 });
130 /// ```
131 pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {
132 Point {
133 x: f(self.x.clone()),
134 y: f(self.y.clone()),
135 }
136 }
137}
138
139impl<T: Clone + Debug + Default> Along for Point<T> {
140 type Unit = T;
141
142 fn along(&self, axis: Axis) -> T {
143 match axis {
144 Axis::Horizontal => self.x.clone(),
145 Axis::Vertical => self.y.clone(),
146 }
147 }
148
149 fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Point<T> {
150 match axis {
151 Axis::Horizontal => Point {
152 x: f(self.x.clone()),
153 y: self.y.clone(),
154 },
155 Axis::Vertical => Point {
156 x: self.x.clone(),
157 y: f(self.y.clone()),
158 },
159 }
160 }
161}
162
163impl<T: Clone + Debug + Default + Negate> Negate for Point<T> {
164 fn negate(self) -> Self {
165 self.map(Negate::negate)
166 }
167}
168
169impl Point<Pixels> {
170 /// Scales the point by a given factor, which is typically derived from the resolution
171 /// of a target display to ensure proper sizing of UI elements.
172 ///
173 /// # Arguments
174 ///
175 /// * `factor` - The scaling factor to apply to both the x and y coordinates.
176 ///
177 /// # Examples
178 ///
179 /// ```
180 /// # use zed::{Point, Pixels, ScaledPixels};
181 /// let p = Point { x: Pixels(10.0), y: Pixels(20.0) };
182 /// let scaled_p = p.scale(1.5);
183 /// assert_eq!(scaled_p, Point { x: ScaledPixels(15.0), y: ScaledPixels(30.0) });
184 /// ```
185 pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {
186 Point {
187 x: self.x.scale(factor),
188 y: self.y.scale(factor),
189 }
190 }
191
192 /// Calculates the Euclidean distance from the origin (0, 0) to this point.
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// # use zed::Point;
198 /// # use zed::Pixels;
199 /// let p = Point { x: Pixels(3.0), y: Pixels(4.0) };
200 /// assert_eq!(p.magnitude(), 5.0);
201 /// ```
202 pub fn magnitude(&self) -> f64 {
203 ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt()
204 }
205}
206
207impl<T, Rhs> Mul<Rhs> for Point<T>
208where
209 T: Mul<Rhs, Output = T> + Clone + Default + Debug,
210 Rhs: Clone + Debug,
211{
212 type Output = Point<T>;
213
214 fn mul(self, rhs: Rhs) -> Self::Output {
215 Point {
216 x: self.x * rhs.clone(),
217 y: self.y * rhs,
218 }
219 }
220}
221
222impl<T, S> MulAssign<S> for Point<T>
223where
224 T: Clone + Mul<S, Output = T> + Default + Debug,
225 S: Clone,
226{
227 fn mul_assign(&mut self, rhs: S) {
228 self.x = self.x.clone() * rhs.clone();
229 self.y = self.y.clone() * rhs;
230 }
231}
232
233impl<T, S> Div<S> for Point<T>
234where
235 T: Div<S, Output = T> + Clone + Default + Debug,
236 S: Clone,
237{
238 type Output = Self;
239
240 fn div(self, rhs: S) -> Self::Output {
241 Self {
242 x: self.x / rhs.clone(),
243 y: self.y / rhs,
244 }
245 }
246}
247
248impl<T> Point<T>
249where
250 T: PartialOrd + Clone + Default + Debug,
251{
252 /// Returns a new point with the maximum values of each dimension from `self` and `other`.
253 ///
254 /// # Arguments
255 ///
256 /// * `other` - A reference to another `Point` to compare with `self`.
257 ///
258 /// # Examples
259 ///
260 /// ```
261 /// # use zed::Point;
262 /// let p1 = Point { x: 3, y: 7 };
263 /// let p2 = Point { x: 5, y: 2 };
264 /// let max_point = p1.max(&p2);
265 /// assert_eq!(max_point, Point { x: 5, y: 7 });
266 /// ```
267 pub fn max(&self, other: &Self) -> Self {
268 Point {
269 x: if self.x > other.x {
270 self.x.clone()
271 } else {
272 other.x.clone()
273 },
274 y: if self.y > other.y {
275 self.y.clone()
276 } else {
277 other.y.clone()
278 },
279 }
280 }
281
282 /// Returns a new point with the minimum values of each dimension from `self` and `other`.
283 ///
284 /// # Arguments
285 ///
286 /// * `other` - A reference to another `Point` to compare with `self`.
287 ///
288 /// # Examples
289 ///
290 /// ```
291 /// # use zed::Point;
292 /// let p1 = Point { x: 3, y: 7 };
293 /// let p2 = Point { x: 5, y: 2 };
294 /// let min_point = p1.min(&p2);
295 /// assert_eq!(min_point, Point { x: 3, y: 2 });
296 /// ```
297 pub fn min(&self, other: &Self) -> Self {
298 Point {
299 x: if self.x <= other.x {
300 self.x.clone()
301 } else {
302 other.x.clone()
303 },
304 y: if self.y <= other.y {
305 self.y.clone()
306 } else {
307 other.y.clone()
308 },
309 }
310 }
311
312 /// Clamps the point to a specified range.
313 ///
314 /// Given a minimum point and a maximum point, this method constrains the current point
315 /// such that its coordinates do not exceed the range defined by the minimum and maximum points.
316 /// If the current point's coordinates are less than the minimum, they are set to the minimum.
317 /// If they are greater than the maximum, they are set to the maximum.
318 ///
319 /// # Arguments
320 ///
321 /// * `min` - A reference to a `Point` representing the minimum allowable coordinates.
322 /// * `max` - A reference to a `Point` representing the maximum allowable coordinates.
323 ///
324 /// # Examples
325 ///
326 /// ```
327 /// # use zed::Point;
328 /// let p = Point { x: 10, y: 20 };
329 /// let min = Point { x: 0, y: 5 };
330 /// let max = Point { x: 15, y: 25 };
331 /// let clamped_p = p.clamp(&min, &max);
332 /// assert_eq!(clamped_p, Point { x: 10, y: 20 });
333 ///
334 /// let p_out_of_bounds = Point { x: -5, y: 30 };
335 /// let clamped_p_out_of_bounds = p_out_of_bounds.clamp(&min, &max);
336 /// assert_eq!(clamped_p_out_of_bounds, Point { x: 0, y: 25 });
337 /// ```
338 pub fn clamp(&self, min: &Self, max: &Self) -> Self {
339 self.max(min).min(max)
340 }
341}
342
343impl<T: Clone + Default + Debug> Clone for Point<T> {
344 fn clone(&self) -> Self {
345 Self {
346 x: self.x.clone(),
347 y: self.y.clone(),
348 }
349 }
350}
351
352/// A structure representing a two-dimensional size with width and height in a given unit.
353///
354/// This struct is generic over the type `T`, which can be any type that implements `Clone`, `Default`, and `Debug`.
355/// It is commonly used to specify dimensions for elements in a UI, such as a window or element.
356#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
357#[refineable(Debug)]
358#[repr(C)]
359pub struct Size<T: Clone + Default + Debug> {
360 /// The width component of the size.
361 pub width: T,
362 /// The height component of the size.
363 pub height: T,
364}
365
366impl From<Size<DevicePixels>> for Size<Pixels> {
367 fn from(size: Size<DevicePixels>) -> Self {
368 Size {
369 width: Pixels(size.width.0 as f32),
370 height: Pixels(size.height.0 as f32),
371 }
372 }
373}
374
375/// Constructs a new `Size<T>` with the provided width and height.
376///
377/// # Arguments
378///
379/// * `width` - The width component of the `Size`.
380/// * `height` - The height component of the `Size`.
381///
382/// # Examples
383///
384/// ```
385/// # use zed::Size;
386/// let my_size = size(10, 20);
387/// assert_eq!(my_size.width, 10);
388/// assert_eq!(my_size.height, 20);
389/// ```
390pub const fn size<T>(width: T, height: T) -> Size<T>
391where
392 T: Clone + Default + Debug,
393{
394 Size { width, height }
395}
396
397impl<T> Size<T>
398where
399 T: Clone + Default + Debug,
400{
401 /// Applies a function to the width and height of the size, producing a new `Size<U>`.
402 ///
403 /// This method allows for converting a `Size<T>` to a `Size<U>` by specifying a closure
404 /// that defines how to convert between the two types. The closure is applied to both the `width`
405 /// and `height`, resulting in a new size of the desired type.
406 ///
407 /// # Arguments
408 ///
409 /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
410 ///
411 /// # Examples
412 ///
413 /// ```
414 /// # use zed::Size;
415 /// let my_size = Size { width: 10, height: 20 };
416 /// let my_new_size = my_size.map(|dimension| dimension as f32 * 1.5);
417 /// assert_eq!(my_new_size, Size { width: 15.0, height: 30.0 });
418 /// ```
419 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>
420 where
421 U: Clone + Default + Debug,
422 {
423 Size {
424 width: f(self.width.clone()),
425 height: f(self.height.clone()),
426 }
427 }
428}
429
430impl<T> Size<T>
431where
432 T: Clone + Default + Debug + Half,
433{
434 /// Compute the center point of the size.g
435 pub fn center(&self) -> Point<T> {
436 Point {
437 x: self.width.half(),
438 y: self.height.half(),
439 }
440 }
441}
442
443impl Size<Pixels> {
444 /// Scales the size by a given factor.
445 ///
446 /// This method multiplies both the width and height by the provided scaling factor,
447 /// resulting in a new `Size<ScaledPixels>` that is proportionally larger or smaller
448 /// depending on the factor.
449 ///
450 /// # Arguments
451 ///
452 /// * `factor` - The scaling factor to apply to the width and height.
453 ///
454 /// # Examples
455 ///
456 /// ```
457 /// # use zed::{Size, Pixels, ScaledPixels};
458 /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
459 /// let scaled_size = size.scale(2.0);
460 /// assert_eq!(scaled_size, Size { width: ScaledPixels(200.0), height: ScaledPixels(100.0) });
461 /// ```
462 pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {
463 Size {
464 width: self.width.scale(factor),
465 height: self.height.scale(factor),
466 }
467 }
468}
469
470impl<T> Along for Size<T>
471where
472 T: Clone + Default + Debug,
473{
474 type Unit = T;
475
476 fn along(&self, axis: Axis) -> T {
477 match axis {
478 Axis::Horizontal => self.width.clone(),
479 Axis::Vertical => self.height.clone(),
480 }
481 }
482
483 /// Returns the value of this size along the given axis.
484 fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Self {
485 match axis {
486 Axis::Horizontal => Size {
487 width: f(self.width.clone()),
488 height: self.height.clone(),
489 },
490 Axis::Vertical => Size {
491 width: self.width.clone(),
492 height: f(self.height.clone()),
493 },
494 }
495 }
496}
497
498impl<T> Size<T>
499where
500 T: PartialOrd + Clone + Default + Debug,
501{
502 /// Returns a new `Size` with the maximum width and height from `self` and `other`.
503 ///
504 /// # Arguments
505 ///
506 /// * `other` - A reference to another `Size` to compare with `self`.
507 ///
508 /// # Examples
509 ///
510 /// ```
511 /// # use zed::Size;
512 /// let size1 = Size { width: 30, height: 40 };
513 /// let size2 = Size { width: 50, height: 20 };
514 /// let max_size = size1.max(&size2);
515 /// assert_eq!(max_size, Size { width: 50, height: 40 });
516 /// ```
517 pub fn max(&self, other: &Self) -> Self {
518 Size {
519 width: if self.width >= other.width {
520 self.width.clone()
521 } else {
522 other.width.clone()
523 },
524 height: if self.height >= other.height {
525 self.height.clone()
526 } else {
527 other.height.clone()
528 },
529 }
530 }
531 /// Returns a new `Size` with the minimum width and height from `self` and `other`.
532 ///
533 /// # Arguments
534 ///
535 /// * `other` - A reference to another `Size` to compare with `self`.
536 ///
537 /// # Examples
538 ///
539 /// ```
540 /// # use zed::Size;
541 /// let size1 = Size { width: 30, height: 40 };
542 /// let size2 = Size { width: 50, height: 20 };
543 /// let min_size = size1.min(&size2);
544 /// assert_eq!(min_size, Size { width: 30, height: 20 });
545 /// ```
546 pub fn min(&self, other: &Self) -> Self {
547 Size {
548 width: if self.width >= other.width {
549 other.width.clone()
550 } else {
551 self.width.clone()
552 },
553 height: if self.height >= other.height {
554 other.height.clone()
555 } else {
556 self.height.clone()
557 },
558 }
559 }
560}
561
562impl<T> Sub for Size<T>
563where
564 T: Sub<Output = T> + Clone + Default + Debug,
565{
566 type Output = Size<T>;
567
568 fn sub(self, rhs: Self) -> Self::Output {
569 Size {
570 width: self.width - rhs.width,
571 height: self.height - rhs.height,
572 }
573 }
574}
575
576impl<T> Add for Size<T>
577where
578 T: Add<Output = T> + Clone + Default + Debug,
579{
580 type Output = Size<T>;
581
582 fn add(self, rhs: Self) -> Self::Output {
583 Size {
584 width: self.width + rhs.width,
585 height: self.height + rhs.height,
586 }
587 }
588}
589
590impl<T, Rhs> Mul<Rhs> for Size<T>
591where
592 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
593 Rhs: Clone + Default + Debug,
594{
595 type Output = Size<Rhs>;
596
597 fn mul(self, rhs: Rhs) -> Self::Output {
598 Size {
599 width: self.width * rhs.clone(),
600 height: self.height * rhs,
601 }
602 }
603}
604
605impl<T, S> MulAssign<S> for Size<T>
606where
607 T: Mul<S, Output = T> + Clone + Default + Debug,
608 S: Clone,
609{
610 fn mul_assign(&mut self, rhs: S) {
611 self.width = self.width.clone() * rhs.clone();
612 self.height = self.height.clone() * rhs;
613 }
614}
615
616impl<T> Eq for Size<T> where T: Eq + Default + Debug + Clone {}
617
618impl<T> Debug for Size<T>
619where
620 T: Clone + Default + Debug,
621{
622 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
623 write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height)
624 }
625}
626
627impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
628 fn from(point: Point<T>) -> Self {
629 Self {
630 width: point.x,
631 height: point.y,
632 }
633 }
634}
635
636impl From<Size<Pixels>> for Size<DevicePixels> {
637 fn from(size: Size<Pixels>) -> Self {
638 Size {
639 width: DevicePixels(size.width.0 as i32),
640 height: DevicePixels(size.height.0 as i32),
641 }
642 }
643}
644
645impl From<Size<Pixels>> for Size<DefiniteLength> {
646 fn from(size: Size<Pixels>) -> Self {
647 Size {
648 width: size.width.into(),
649 height: size.height.into(),
650 }
651 }
652}
653
654impl From<Size<Pixels>> for Size<AbsoluteLength> {
655 fn from(size: Size<Pixels>) -> Self {
656 Size {
657 width: size.width.into(),
658 height: size.height.into(),
659 }
660 }
661}
662
663impl Size<Length> {
664 /// Returns a `Size` with both width and height set to fill the available space.
665 ///
666 /// This function creates a `Size` instance where both the width and height are set to `Length::Definite(DefiniteLength::Fraction(1.0))`,
667 /// which represents 100% of the available space in both dimensions.
668 ///
669 /// # Returns
670 ///
671 /// A `Size<Length>` that will fill the available space when used in a layout.
672 pub fn full() -> Self {
673 Self {
674 width: relative(1.).into(),
675 height: relative(1.).into(),
676 }
677 }
678}
679
680impl Size<Length> {
681 /// Returns a `Size` with both width and height set to `auto`, which allows the layout engine to determine the size.
682 ///
683 /// This function creates a `Size` instance where both the width and height are set to `Length::Auto`,
684 /// indicating that their size should be computed based on the layout context, such as the content size or
685 /// available space.
686 ///
687 /// # Returns
688 ///
689 /// A `Size<Length>` with width and height set to `Length::Auto`.
690 pub fn auto() -> Self {
691 Self {
692 width: Length::Auto,
693 height: Length::Auto,
694 }
695 }
696}
697
698/// Represents a rectangular area in a 2D space with an origin point and a size.
699///
700/// The `Bounds` struct is generic over a type `T` which represents the type of the coordinate system.
701/// The origin is represented as a `Point<T>` which defines the upper-left corner of the rectangle,
702/// and the size is represented as a `Size<T>` which defines the width and height of the rectangle.
703///
704/// # Examples
705///
706/// ```
707/// # use zed::{Bounds, Point, Size};
708/// let origin = Point { x: 0, y: 0 };
709/// let size = Size { width: 10, height: 20 };
710/// let bounds = Bounds::new(origin, size);
711///
712/// assert_eq!(bounds.origin, origin);
713/// assert_eq!(bounds.size, size);
714/// ```
715#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
716#[refineable(Debug)]
717#[repr(C)]
718pub struct Bounds<T: Clone + Default + Debug> {
719 /// The origin point of this area.
720 pub origin: Point<T>,
721 /// The size of the rectangle.
722 pub size: Size<T>,
723}
724
725impl Bounds<DevicePixels> {
726 /// Generate a centered bounds for the given display or primary display if none is provided
727 pub fn centered(
728 display_id: Option<DisplayId>,
729 size: impl Into<Size<DevicePixels>>,
730 cx: &mut AppContext,
731 ) -> Self {
732 let display = display_id
733 .and_then(|id| cx.find_display(id))
734 .or_else(|| cx.primary_display());
735
736 let size = size.into();
737 display
738 .map(|display| {
739 let center = display.bounds().center();
740 Bounds {
741 origin: point(center.x - size.width / 2, center.y - size.height / 2),
742 size,
743 }
744 })
745 .unwrap_or_else(|| Bounds {
746 origin: point(DevicePixels(0), DevicePixels(0)),
747 size,
748 })
749 }
750
751 /// Generate maximized bounds for the given display or primary display if none is provided
752 pub fn maximized(display_id: Option<DisplayId>, cx: &mut AppContext) -> Self {
753 let display = display_id
754 .and_then(|id| cx.find_display(id))
755 .or_else(|| cx.primary_display());
756
757 display
758 .map(|display| display.bounds())
759 .unwrap_or_else(|| Bounds {
760 origin: point(DevicePixels(0), DevicePixels(0)),
761 size: size(DevicePixels(1024), DevicePixels(768)),
762 })
763 }
764}
765
766impl<T> Bounds<T>
767where
768 T: Clone + Debug + Sub<Output = T> + Default,
769{
770 /// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners.
771 ///
772 /// This function calculates the origin and size of the `Bounds` based on the provided corner points.
773 /// The origin is set to the upper-left corner, and the size is determined by the difference between
774 /// the x and y coordinates of the lower-right and upper-left points.
775 ///
776 /// # Arguments
777 ///
778 /// * `upper_left` - A `Point<T>` representing the upper-left corner of the rectangle.
779 /// * `lower_right` - A `Point<T>` representing the lower-right corner of the rectangle.
780 ///
781 /// # Returns
782 ///
783 /// Returns a `Bounds<T>` that encompasses the area defined by the two corner points.
784 ///
785 /// # Examples
786 ///
787 /// ```
788 /// # use zed::{Bounds, Point};
789 /// let upper_left = Point { x: 0, y: 0 };
790 /// let lower_right = Point { x: 10, y: 10 };
791 /// let bounds = Bounds::from_corners(upper_left, lower_right);
792 ///
793 /// assert_eq!(bounds.origin, upper_left);
794 /// assert_eq!(bounds.size.width, 10);
795 /// assert_eq!(bounds.size.height, 10);
796 /// ```
797 pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
798 let origin = Point {
799 x: upper_left.x.clone(),
800 y: upper_left.y.clone(),
801 };
802 let size = Size {
803 width: lower_right.x - upper_left.x,
804 height: lower_right.y - upper_left.y,
805 };
806 Bounds { origin, size }
807 }
808
809 /// Creates a new `Bounds` with the specified origin and size.
810 ///
811 /// # Arguments
812 ///
813 /// * `origin` - A `Point<T>` representing the origin of the bounds.
814 /// * `size` - A `Size<T>` representing the size of the bounds.
815 ///
816 /// # Returns
817 ///
818 /// Returns a `Bounds<T>` that has the given origin and size.
819 pub fn new(origin: Point<T>, size: Size<T>) -> Self {
820 Bounds { origin, size }
821 }
822}
823
824impl<T> Bounds<T>
825where
826 T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default + Half,
827{
828 /// Checks if this `Bounds` intersects with another `Bounds`.
829 ///
830 /// Two `Bounds` instances intersect if they overlap in the 2D space they occupy.
831 /// This method checks if there is any overlapping area between the two bounds.
832 ///
833 /// # Arguments
834 ///
835 /// * `other` - A reference to another `Bounds` to check for intersection with.
836 ///
837 /// # Returns
838 ///
839 /// Returns `true` if there is any intersection between the two bounds, `false` otherwise.
840 ///
841 /// # Examples
842 ///
843 /// ```
844 /// # use zed::{Bounds, Point, Size};
845 /// let bounds1 = Bounds {
846 /// origin: Point { x: 0, y: 0 },
847 /// size: Size { width: 10, height: 10 },
848 /// };
849 /// let bounds2 = Bounds {
850 /// origin: Point { x: 5, y: 5 },
851 /// size: Size { width: 10, height: 10 },
852 /// };
853 /// let bounds3 = Bounds {
854 /// origin: Point { x: 20, y: 20 },
855 /// size: Size { width: 10, height: 10 },
856 /// };
857 ///
858 /// assert_eq!(bounds1.intersects(&bounds2), true); // Overlapping bounds
859 /// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds
860 /// ```
861 pub fn intersects(&self, other: &Bounds<T>) -> bool {
862 let my_lower_right = self.lower_right();
863 let their_lower_right = other.lower_right();
864
865 self.origin.x < their_lower_right.x
866 && my_lower_right.x > other.origin.x
867 && self.origin.y < their_lower_right.y
868 && my_lower_right.y > other.origin.y
869 }
870
871 /// Dilates the bounds by a specified amount in all directions.
872 ///
873 /// This method expands the bounds by the given `amount`, increasing the size
874 /// and adjusting the origin so that the bounds grow outwards equally in all directions.
875 /// The resulting bounds will have its width and height increased by twice the `amount`
876 /// (since it grows in both directions), and the origin will be moved by `-amount`
877 /// in both the x and y directions.
878 ///
879 /// # Arguments
880 ///
881 /// * `amount` - The amount by which to dilate the bounds.
882 ///
883 /// # Examples
884 ///
885 /// ```
886 /// # use zed::{Bounds, Point, Size};
887 /// let mut bounds = Bounds {
888 /// origin: Point { x: 10, y: 10 },
889 /// size: Size { width: 10, height: 10 },
890 /// };
891 /// bounds.dilate(5);
892 /// assert_eq!(bounds, Bounds {
893 /// origin: Point { x: 5, y: 5 },
894 /// size: Size { width: 20, height: 20 },
895 /// });
896 /// ```
897 pub fn dilate(&mut self, amount: T) {
898 self.origin.x = self.origin.x.clone() - amount.clone();
899 self.origin.y = self.origin.y.clone() - amount.clone();
900 let double_amount = amount.clone() + amount;
901 self.size.width = self.size.width.clone() + double_amount.clone();
902 self.size.height = self.size.height.clone() + double_amount;
903 }
904
905 /// Returns the center point of the bounds.
906 ///
907 /// Calculates the center by taking the origin's x and y coordinates and adding half the width and height
908 /// of the bounds, respectively. The center is represented as a `Point<T>` where `T` is the type of the
909 /// coordinate system.
910 ///
911 /// # Returns
912 ///
913 /// A `Point<T>` representing the center of the bounds.
914 ///
915 /// # Examples
916 ///
917 /// ```
918 /// # use zed::{Bounds, Point, Size};
919 /// let bounds = Bounds {
920 /// origin: Point { x: 0, y: 0 },
921 /// size: Size { width: 10, height: 20 },
922 /// };
923 /// let center = bounds.center();
924 /// assert_eq!(center, Point { x: 5, y: 10 });
925 /// ```
926 pub fn center(&self) -> Point<T> {
927 Point {
928 x: self.origin.x.clone() + self.size.width.clone().half(),
929 y: self.origin.y.clone() + self.size.height.clone().half(),
930 }
931 }
932
933 /// Calculates the half perimeter of a rectangle defined by the bounds.
934 ///
935 /// The half perimeter is calculated as the sum of the width and the height of the rectangle.
936 /// This method is generic over the type `T` which must implement the `Sub` trait to allow
937 /// calculation of the width and height from the bounds' origin and size, as well as the `Add` trait
938 /// to sum the width and height for the half perimeter.
939 ///
940 /// # Examples
941 ///
942 /// ```
943 /// # use zed::{Bounds, Point, Size};
944 /// let bounds = Bounds {
945 /// origin: Point { x: 0, y: 0 },
946 /// size: Size { width: 10, height: 20 },
947 /// };
948 /// let half_perimeter = bounds.half_perimeter();
949 /// assert_eq!(half_perimeter, 30);
950 /// ```
951 pub fn half_perimeter(&self) -> T {
952 self.size.width.clone() + self.size.height.clone()
953 }
954}
955
956impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
957 /// Calculates the intersection of two `Bounds` objects.
958 ///
959 /// This method computes the overlapping region of two `Bounds`. If the bounds do not intersect,
960 /// the resulting `Bounds` will have a size with width and height of zero.
961 ///
962 /// # Arguments
963 ///
964 /// * `other` - A reference to another `Bounds` to intersect with.
965 ///
966 /// # Returns
967 ///
968 /// Returns a `Bounds` representing the intersection area. If there is no intersection,
969 /// the returned `Bounds` will have a size with width and height of zero.
970 ///
971 /// # Examples
972 ///
973 /// ```
974 /// # use zed::{Bounds, Point, Size};
975 /// let bounds1 = Bounds {
976 /// origin: Point { x: 0, y: 0 },
977 /// size: Size { width: 10, height: 10 },
978 /// };
979 /// let bounds2 = Bounds {
980 /// origin: Point { x: 5, y: 5 },
981 /// size: Size { width: 10, height: 10 },
982 /// };
983 /// let intersection = bounds1.intersect(&bounds2);
984 ///
985 /// assert_eq!(intersection, Bounds {
986 /// origin: Point { x: 5, y: 5 },
987 /// size: Size { width: 5, height: 5 },
988 /// });
989 /// ```
990 pub fn intersect(&self, other: &Self) -> Self {
991 let upper_left = self.origin.max(&other.origin);
992 let lower_right = self.lower_right().min(&other.lower_right());
993 Self::from_corners(upper_left, lower_right)
994 }
995
996 /// Computes the union of two `Bounds`.
997 ///
998 /// This method calculates the smallest `Bounds` that contains both the current `Bounds` and the `other` `Bounds`.
999 /// The resulting `Bounds` will have an origin that is the minimum of the origins of the two `Bounds`,
1000 /// and a size that encompasses the furthest extents of both `Bounds`.
1001 ///
1002 /// # Arguments
1003 ///
1004 /// * `other` - A reference to another `Bounds` to create a union with.
1005 ///
1006 /// # Returns
1007 ///
1008 /// Returns a `Bounds` representing the union of the two `Bounds`.
1009 ///
1010 /// # Examples
1011 ///
1012 /// ```
1013 /// # use zed::{Bounds, Point, Size};
1014 /// let bounds1 = Bounds {
1015 /// origin: Point { x: 0, y: 0 },
1016 /// size: Size { width: 10, height: 10 },
1017 /// };
1018 /// let bounds2 = Bounds {
1019 /// origin: Point { x: 5, y: 5 },
1020 /// size: Size { width: 15, height: 15 },
1021 /// };
1022 /// let union_bounds = bounds1.union(&bounds2);
1023 ///
1024 /// assert_eq!(union_bounds, Bounds {
1025 /// origin: Point { x: 0, y: 0 },
1026 /// size: Size { width: 20, height: 20 },
1027 /// });
1028 /// ```
1029 pub fn union(&self, other: &Self) -> Self {
1030 let top_left = self.origin.min(&other.origin);
1031 let bottom_right = self.lower_right().max(&other.lower_right());
1032 Bounds::from_corners(top_left, bottom_right)
1033 }
1034}
1035
1036impl<T, Rhs> Mul<Rhs> for Bounds<T>
1037where
1038 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
1039 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
1040 Rhs: Clone + Default + Debug,
1041{
1042 type Output = Bounds<Rhs>;
1043
1044 fn mul(self, rhs: Rhs) -> Self::Output {
1045 Bounds {
1046 origin: self.origin * rhs.clone(),
1047 size: self.size * rhs,
1048 }
1049 }
1050}
1051
1052impl<T, S> MulAssign<S> for Bounds<T>
1053where
1054 T: Mul<S, Output = T> + Clone + Default + Debug,
1055 S: Clone,
1056{
1057 fn mul_assign(&mut self, rhs: S) {
1058 self.origin *= rhs.clone();
1059 self.size *= rhs;
1060 }
1061}
1062
1063impl<T, S> Div<S> for Bounds<T>
1064where
1065 Size<T>: Div<S, Output = Size<T>>,
1066 T: Div<S, Output = T> + Default + Clone + Debug,
1067 S: Clone,
1068{
1069 type Output = Self;
1070
1071 fn div(self, rhs: S) -> Self {
1072 Self {
1073 origin: self.origin / rhs.clone(),
1074 size: self.size / rhs,
1075 }
1076 }
1077}
1078
1079impl<T> Bounds<T>
1080where
1081 T: Add<T, Output = T> + Clone + Default + Debug,
1082{
1083 /// Returns the top edge of the bounds.
1084 ///
1085 /// # Returns
1086 ///
1087 /// A value of type `T` representing the y-coordinate of the top edge of the bounds.
1088 pub fn top(&self) -> T {
1089 self.origin.y.clone()
1090 }
1091
1092 /// Returns the bottom edge of the bounds.
1093 ///
1094 /// # Returns
1095 ///
1096 /// A value of type `T` representing the y-coordinate of the bottom edge of the bounds.
1097 pub fn bottom(&self) -> T {
1098 self.origin.y.clone() + self.size.height.clone()
1099 }
1100
1101 /// Returns the left edge of the bounds.
1102 ///
1103 /// # Returns
1104 ///
1105 /// A value of type `T` representing the x-coordinate of the left edge of the bounds.
1106 pub fn left(&self) -> T {
1107 self.origin.x.clone()
1108 }
1109
1110 /// Returns the right edge of the bounds.
1111 ///
1112 /// # Returns
1113 ///
1114 /// A value of type `T` representing the x-coordinate of the right edge of the bounds.
1115 pub fn right(&self) -> T {
1116 self.origin.x.clone() + self.size.width.clone()
1117 }
1118
1119 /// Returns the upper-right corner point of the bounds.
1120 ///
1121 /// # Returns
1122 ///
1123 /// A `Point<T>` representing the upper-right corner of the bounds.
1124 ///
1125 /// # Examples
1126 ///
1127 /// ```
1128 /// # use zed::{Bounds, Point, Size};
1129 /// let bounds = Bounds {
1130 /// origin: Point { x: 0, y: 0 },
1131 /// size: Size { width: 10, height: 20 },
1132 /// };
1133 /// let upper_right = bounds.upper_right();
1134 /// assert_eq!(upper_right, Point { x: 10, y: 0 });
1135 /// ```
1136 pub fn upper_right(&self) -> Point<T> {
1137 Point {
1138 x: self.origin.x.clone() + self.size.width.clone(),
1139 y: self.origin.y.clone(),
1140 }
1141 }
1142
1143 /// Returns the lower-right corner point of the bounds.
1144 ///
1145 /// # Returns
1146 ///
1147 /// A `Point<T>` representing the lower-right corner of the bounds.
1148 ///
1149 /// # Examples
1150 ///
1151 /// ```
1152 /// # use zed::{Bounds, Point, Size};
1153 /// let bounds = Bounds {
1154 /// origin: Point { x: 0, y: 0 },
1155 /// size: Size { width: 10, height: 20 },
1156 /// };
1157 /// let lower_right = bounds.lower_right();
1158 /// assert_eq!(lower_right, Point { x: 10, y: 20 });
1159 /// ```
1160 pub fn lower_right(&self) -> Point<T> {
1161 Point {
1162 x: self.origin.x.clone() + self.size.width.clone(),
1163 y: self.origin.y.clone() + self.size.height.clone(),
1164 }
1165 }
1166
1167 /// Returns the lower-left corner point of the bounds.
1168 ///
1169 /// # Returns
1170 ///
1171 /// A `Point<T>` representing the lower-left corner of the bounds.
1172 ///
1173 /// # Examples
1174 ///
1175 /// ```
1176 /// # use zed::{Bounds, Point, Size};
1177 /// let bounds = Bounds {
1178 /// origin: Point { x: 0, y: 0 },
1179 /// size: Size { width: 10, height: 20 },
1180 /// };
1181 /// let lower_left = bounds.lower_left();
1182 /// assert_eq!(lower_left, Point { x: 0, y: 20 });
1183 /// ```
1184 pub fn lower_left(&self) -> Point<T> {
1185 Point {
1186 x: self.origin.x.clone(),
1187 y: self.origin.y.clone() + self.size.height.clone(),
1188 }
1189 }
1190}
1191
1192impl<T> Bounds<T>
1193where
1194 T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
1195{
1196 /// Checks if the given point is within the bounds.
1197 ///
1198 /// This method determines whether a point lies inside the rectangle defined by the bounds,
1199 /// including the edges. The point is considered inside if its x-coordinate is greater than
1200 /// or equal to the left edge and less than or equal to the right edge, and its y-coordinate
1201 /// is greater than or equal to the top edge and less than or equal to the bottom edge of the bounds.
1202 ///
1203 /// # Arguments
1204 ///
1205 /// * `point` - A reference to a `Point<T>` that represents the point to check.
1206 ///
1207 /// # Returns
1208 ///
1209 /// Returns `true` if the point is within the bounds, `false` otherwise.
1210 ///
1211 /// # Examples
1212 ///
1213 /// ```
1214 /// # use zed::{Point, Bounds};
1215 /// let bounds = Bounds {
1216 /// origin: Point { x: 0, y: 0 },
1217 /// size: Size { width: 10, height: 10 },
1218 /// };
1219 /// let inside_point = Point { x: 5, y: 5 };
1220 /// let outside_point = Point { x: 15, y: 15 };
1221 ///
1222 /// assert!(bounds.contains_point(&inside_point));
1223 /// assert!(!bounds.contains_point(&outside_point));
1224 /// ```
1225 pub fn contains(&self, point: &Point<T>) -> bool {
1226 point.x >= self.origin.x
1227 && point.x <= self.origin.x.clone() + self.size.width.clone()
1228 && point.y >= self.origin.y
1229 && point.y <= self.origin.y.clone() + self.size.height.clone()
1230 }
1231
1232 /// Applies a function to the origin and size of the bounds, producing a new `Bounds<U>`.
1233 ///
1234 /// This method allows for converting a `Bounds<T>` to a `Bounds<U>` by specifying a closure
1235 /// that defines how to convert between the two types. The closure is applied to the `origin` and
1236 /// `size` fields, resulting in new bounds of the desired type.
1237 ///
1238 /// # Arguments
1239 ///
1240 /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
1241 ///
1242 /// # Returns
1243 ///
1244 /// Returns a new `Bounds<U>` with the origin and size mapped by the provided function.
1245 ///
1246 /// # Examples
1247 ///
1248 /// ```
1249 /// # use zed::{Bounds, Point, Size};
1250 /// let bounds = Bounds {
1251 /// origin: Point { x: 10.0, y: 10.0 },
1252 /// size: Size { width: 10.0, height: 20.0 },
1253 /// };
1254 /// let new_bounds = bounds.map(|value| value as f64 * 1.5);
1255 ///
1256 /// assert_eq!(new_bounds, Bounds {
1257 /// origin: Point { x: 15.0, y: 15.0 },
1258 /// size: Size { width: 15.0, height: 30.0 },
1259 /// });
1260 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
1261 where
1262 U: Clone + Default + Debug,
1263 {
1264 Bounds {
1265 origin: self.origin.map(&f),
1266 size: self.size.map(f),
1267 }
1268 }
1269
1270 /// Applies a function to the origin of the bounds, producing a new `Bounds` with the new origin
1271 ///
1272 /// # Examples
1273 ///
1274 /// ```
1275 /// # use zed::{Bounds, Point, Size};
1276 /// let bounds = Bounds {
1277 /// origin: Point { x: 10.0, y: 10.0 },
1278 /// size: Size { width: 10.0, height: 20.0 },
1279 /// };
1280 /// let new_bounds = bounds.map_origin(|value| value * 1.5);
1281 ///
1282 /// assert_eq!(new_bounds, Bounds {
1283 /// origin: Point { x: 15.0, y: 15.0 },
1284 /// size: Size { width: 10.0, height: 20.0 },
1285 /// });
1286 pub fn map_origin(self, f: impl Fn(Point<T>) -> Point<T>) -> Bounds<T> {
1287 Bounds {
1288 origin: f(self.origin),
1289 size: self.size,
1290 }
1291 }
1292}
1293
1294/// Checks if the bounds represent an empty area.
1295///
1296/// # Returns
1297///
1298/// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1299impl<T: PartialOrd + Default + Debug + Clone> Bounds<T> {
1300 /// Checks if the bounds represent an empty area.
1301 ///
1302 /// # Returns
1303 ///
1304 /// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1305 pub fn is_empty(&self) -> bool {
1306 self.size.width <= T::default() || self.size.height <= T::default()
1307 }
1308}
1309
1310impl Bounds<Pixels> {
1311 /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1312 ///
1313 /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1314 /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1315 /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1316 /// scaled for different display densities.
1317 ///
1318 /// # Arguments
1319 ///
1320 /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1321 ///
1322 /// # Returns
1323 ///
1324 /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1325 ///
1326 /// # Examples
1327 ///
1328 /// ```
1329 /// # use zed::{Bounds, Point, Size, Pixels};
1330 /// let bounds = Bounds {
1331 /// origin: Point { x: Pixels(10.0), y: Pixels(20.0) },
1332 /// size: Size { width: Pixels(30.0), height: Pixels(40.0) },
1333 /// };
1334 /// let display_scale_factor = 2.0;
1335 /// let scaled_bounds = bounds.scale(display_scale_factor);
1336 /// assert_eq!(scaled_bounds, Bounds {
1337 /// origin: Point { x: ScaledPixels(20.0), y: ScaledPixels(40.0) },
1338 /// size: Size { width: ScaledPixels(60.0), height: ScaledPixels(80.0) },
1339 /// });
1340 /// ```
1341 pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1342 Bounds {
1343 origin: self.origin.scale(factor),
1344 size: self.size.scale(factor),
1345 }
1346 }
1347}
1348
1349impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
1350
1351/// Represents the edges of a box in a 2D space, such as padding or margin.
1352///
1353/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1354///
1355/// # Examples
1356///
1357/// ```
1358/// # use zed::Edges;
1359/// let edges = Edges {
1360/// top: 10.0,
1361/// right: 20.0,
1362/// bottom: 30.0,
1363/// left: 40.0,
1364/// };
1365///
1366/// assert_eq!(edges.top, 10.0);
1367/// assert_eq!(edges.right, 20.0);
1368/// assert_eq!(edges.bottom, 30.0);
1369/// assert_eq!(edges.left, 40.0);
1370/// ```
1371#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1372#[refineable(Debug)]
1373#[repr(C)]
1374pub struct Edges<T: Clone + Default + Debug> {
1375 /// The size of the top edge.
1376 pub top: T,
1377 /// The size of the right edge.
1378 pub right: T,
1379 /// The size of the bottom edge.
1380 pub bottom: T,
1381 /// The size of the left edge.
1382 pub left: T,
1383}
1384
1385impl<T> Mul for Edges<T>
1386where
1387 T: Mul<Output = T> + Clone + Default + Debug,
1388{
1389 type Output = Self;
1390
1391 fn mul(self, rhs: Self) -> Self::Output {
1392 Self {
1393 top: self.top.clone() * rhs.top,
1394 right: self.right.clone() * rhs.right,
1395 bottom: self.bottom.clone() * rhs.bottom,
1396 left: self.left.clone() * rhs.left,
1397 }
1398 }
1399}
1400
1401impl<T, S> MulAssign<S> for Edges<T>
1402where
1403 T: Mul<S, Output = T> + Clone + Default + Debug,
1404 S: Clone,
1405{
1406 fn mul_assign(&mut self, rhs: S) {
1407 self.top = self.top.clone() * rhs.clone();
1408 self.right = self.right.clone() * rhs.clone();
1409 self.bottom = self.bottom.clone() * rhs.clone();
1410 self.left = self.left.clone() * rhs;
1411 }
1412}
1413
1414impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
1415
1416impl<T: Clone + Default + Debug> Edges<T> {
1417 /// Constructs `Edges` where all sides are set to the same specified value.
1418 ///
1419 /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1420 /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1421 /// such as padding or margin with the same size on all sides.
1422 ///
1423 /// # Arguments
1424 ///
1425 /// * `value` - The value to set for all four sides of the edges.
1426 ///
1427 /// # Returns
1428 ///
1429 /// An `Edges` instance with all sides set to the given value.
1430 ///
1431 /// # Examples
1432 ///
1433 /// ```
1434 /// # use zed::Edges;
1435 /// let uniform_edges = Edges::all(10.0);
1436 /// assert_eq!(uniform_edges.top, 10.0);
1437 /// assert_eq!(uniform_edges.right, 10.0);
1438 /// assert_eq!(uniform_edges.bottom, 10.0);
1439 /// assert_eq!(uniform_edges.left, 10.0);
1440 /// ```
1441 pub fn all(value: T) -> Self {
1442 Self {
1443 top: value.clone(),
1444 right: value.clone(),
1445 bottom: value.clone(),
1446 left: value,
1447 }
1448 }
1449
1450 /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1451 ///
1452 /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1453 /// that defines how to convert between the two types. The closure is applied to each field
1454 /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1455 ///
1456 /// # Arguments
1457 ///
1458 /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1459 ///
1460 /// # Returns
1461 ///
1462 /// Returns a new `Edges<U>` with each field mapped by the provided function.
1463 ///
1464 /// # Examples
1465 ///
1466 /// ```
1467 /// # use zed::Edges;
1468 /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1469 /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1470 /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1471 /// ```
1472 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1473 where
1474 U: Clone + Default + Debug,
1475 {
1476 Edges {
1477 top: f(&self.top),
1478 right: f(&self.right),
1479 bottom: f(&self.bottom),
1480 left: f(&self.left),
1481 }
1482 }
1483
1484 /// Checks if any of the edges satisfy a given predicate.
1485 ///
1486 /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1487 ///
1488 /// # Arguments
1489 ///
1490 /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1491 ///
1492 /// # Returns
1493 ///
1494 /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1495 ///
1496 /// # Examples
1497 ///
1498 /// ```
1499 /// # use zed::Edges;
1500 /// let edges = Edges {
1501 /// top: 10,
1502 /// right: 0,
1503 /// bottom: 5,
1504 /// left: 0,
1505 /// };
1506 ///
1507 /// assert!(edges.any(|value| *value == 0));
1508 /// assert!(edges.any(|value| *value > 0));
1509 /// assert!(!edges.any(|value| *value > 10));
1510 /// ```
1511 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1512 predicate(&self.top)
1513 || predicate(&self.right)
1514 || predicate(&self.bottom)
1515 || predicate(&self.left)
1516 }
1517}
1518
1519impl Edges<Length> {
1520 /// Sets the edges of the `Edges` struct to `auto`, which is a special value that allows the layout engine to automatically determine the size of the edges.
1521 ///
1522 /// This is typically used in layout contexts where the exact size of the edges is not important, or when the size should be calculated based on the content or container.
1523 ///
1524 /// # Returns
1525 ///
1526 /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1527 ///
1528 /// # Examples
1529 ///
1530 /// ```
1531 /// # use zed::Edges;
1532 /// let auto_edges = Edges::auto();
1533 /// assert_eq!(auto_edges.top, Length::Auto);
1534 /// assert_eq!(auto_edges.right, Length::Auto);
1535 /// assert_eq!(auto_edges.bottom, Length::Auto);
1536 /// assert_eq!(auto_edges.left, Length::Auto);
1537 /// ```
1538 pub fn auto() -> Self {
1539 Self {
1540 top: Length::Auto,
1541 right: Length::Auto,
1542 bottom: Length::Auto,
1543 left: Length::Auto,
1544 }
1545 }
1546
1547 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1548 ///
1549 /// This is typically used when you want to specify that a box (like a padding or margin area)
1550 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1551 ///
1552 /// # Returns
1553 ///
1554 /// Returns an `Edges<Length>` with all edges set to zero length.
1555 ///
1556 /// # Examples
1557 ///
1558 /// ```
1559 /// # use zed::Edges;
1560 /// let no_edges = Edges::zero();
1561 /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels(0.))));
1562 /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels(0.))));
1563 /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels(0.))));
1564 /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels(0.))));
1565 /// ```
1566 pub fn zero() -> Self {
1567 Self {
1568 top: px(0.).into(),
1569 right: px(0.).into(),
1570 bottom: px(0.).into(),
1571 left: px(0.).into(),
1572 }
1573 }
1574}
1575
1576impl Edges<DefiniteLength> {
1577 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1578 ///
1579 /// This is typically used when you want to specify that a box (like a padding or margin area)
1580 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1581 ///
1582 /// # Returns
1583 ///
1584 /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1585 ///
1586 /// # Examples
1587 ///
1588 /// ```
1589 /// # use zed::Edges;
1590 /// let no_edges = Edges::zero();
1591 /// assert_eq!(no_edges.top, DefiniteLength::from(zed::px(0.)));
1592 /// assert_eq!(no_edges.right, DefiniteLength::from(zed::px(0.)));
1593 /// assert_eq!(no_edges.bottom, DefiniteLength::from(zed::px(0.)));
1594 /// assert_eq!(no_edges.left, DefiniteLength::from(zed::px(0.)));
1595 /// ```
1596 pub fn zero() -> Self {
1597 Self {
1598 top: px(0.).into(),
1599 right: px(0.).into(),
1600 bottom: px(0.).into(),
1601 left: px(0.).into(),
1602 }
1603 }
1604
1605 /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1606 ///
1607 /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1608 /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1609 ///
1610 /// # Arguments
1611 ///
1612 /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1613 /// * `rem_size` - `Pixels` representing the size of one REM unit.
1614 ///
1615 /// # Returns
1616 ///
1617 /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1618 ///
1619 /// # Examples
1620 ///
1621 /// ```
1622 /// # use zed::{Edges, DefiniteLength, px, AbsoluteLength, Size};
1623 /// let edges = Edges {
1624 /// top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1625 /// right: DefiniteLength::Fraction(0.5),
1626 /// bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1627 /// left: DefiniteLength::Fraction(0.25),
1628 /// };
1629 /// let parent_size = Size {
1630 /// width: AbsoluteLength::Pixels(px(200.0)),
1631 /// height: AbsoluteLength::Pixels(px(100.0)),
1632 /// };
1633 /// let rem_size = px(16.0);
1634 /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1635 ///
1636 /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1637 /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1638 /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1639 /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1640 /// ```
1641 pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1642 Edges {
1643 top: self.top.to_pixels(parent_size.height, rem_size),
1644 right: self.right.to_pixels(parent_size.width, rem_size),
1645 bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1646 left: self.left.to_pixels(parent_size.width, rem_size),
1647 }
1648 }
1649}
1650
1651impl Edges<AbsoluteLength> {
1652 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1653 ///
1654 /// This is typically used when you want to specify that a box (like a padding or margin area)
1655 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1656 ///
1657 /// # Returns
1658 ///
1659 /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
1660 ///
1661 /// # Examples
1662 ///
1663 /// ```
1664 /// # use zed::Edges;
1665 /// let no_edges = Edges::zero();
1666 /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels(0.0)));
1667 /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels(0.0)));
1668 /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels(0.0)));
1669 /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels(0.0)));
1670 /// ```
1671 pub fn zero() -> Self {
1672 Self {
1673 top: px(0.).into(),
1674 right: px(0.).into(),
1675 bottom: px(0.).into(),
1676 left: px(0.).into(),
1677 }
1678 }
1679
1680 /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
1681 ///
1682 /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
1683 /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
1684 ///
1685 /// # Arguments
1686 ///
1687 /// * `rem_size` - The size of one rem unit in pixels.
1688 ///
1689 /// # Returns
1690 ///
1691 /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1692 ///
1693 /// # Examples
1694 ///
1695 /// ```
1696 /// # use zed::{Edges, AbsoluteLength, Pixels, px};
1697 /// let edges = Edges {
1698 /// top: AbsoluteLength::Pixels(px(10.0)),
1699 /// right: AbsoluteLength::Rems(rems(1.0)),
1700 /// bottom: AbsoluteLength::Pixels(px(20.0)),
1701 /// left: AbsoluteLength::Rems(rems(2.0)),
1702 /// };
1703 /// let rem_size = px(16.0);
1704 /// let edges_in_pixels = edges.to_pixels(rem_size);
1705 ///
1706 /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
1707 /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
1708 /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
1709 /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
1710 /// ```
1711 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
1712 Edges {
1713 top: self.top.to_pixels(rem_size),
1714 right: self.right.to_pixels(rem_size),
1715 bottom: self.bottom.to_pixels(rem_size),
1716 left: self.left.to_pixels(rem_size),
1717 }
1718 }
1719}
1720
1721impl Edges<Pixels> {
1722 /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
1723 ///
1724 /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
1725 ///
1726 /// # Arguments
1727 ///
1728 /// * `factor` - The scaling factor to apply to each edge.
1729 ///
1730 /// # Returns
1731 ///
1732 /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
1733 ///
1734 /// # Examples
1735 ///
1736 /// ```
1737 /// # use zed::{Edges, Pixels};
1738 /// let edges = Edges {
1739 /// top: Pixels(10.0),
1740 /// right: Pixels(20.0),
1741 /// bottom: Pixels(30.0),
1742 /// left: Pixels(40.0),
1743 /// };
1744 /// let scaled_edges = edges.scale(2.0);
1745 /// assert_eq!(scaled_edges.top, ScaledPixels(20.0));
1746 /// assert_eq!(scaled_edges.right, ScaledPixels(40.0));
1747 /// assert_eq!(scaled_edges.bottom, ScaledPixels(60.0));
1748 /// assert_eq!(scaled_edges.left, ScaledPixels(80.0));
1749 /// ```
1750 pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
1751 Edges {
1752 top: self.top.scale(factor),
1753 right: self.right.scale(factor),
1754 bottom: self.bottom.scale(factor),
1755 left: self.left.scale(factor),
1756 }
1757 }
1758
1759 /// Returns the maximum value of any edge.
1760 ///
1761 /// # Returns
1762 ///
1763 /// The maximum `Pixels` value among all four edges.
1764 pub fn max(&self) -> Pixels {
1765 self.top.max(self.right).max(self.bottom).max(self.left)
1766 }
1767}
1768
1769impl From<f32> for Edges<Pixels> {
1770 fn from(val: f32) -> Self {
1771 Edges {
1772 top: val.into(),
1773 right: val.into(),
1774 bottom: val.into(),
1775 left: val.into(),
1776 }
1777 }
1778}
1779
1780/// Represents the corners of a box in a 2D space, such as border radius.
1781///
1782/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
1783#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1784#[refineable(Debug)]
1785#[repr(C)]
1786pub struct Corners<T: Clone + Default + Debug> {
1787 /// The value associated with the top left corner.
1788 pub top_left: T,
1789 /// The value associated with the top right corner.
1790 pub top_right: T,
1791 /// The value associated with the bottom right corner.
1792 pub bottom_right: T,
1793 /// The value associated with the bottom left corner.
1794 pub bottom_left: T,
1795}
1796
1797impl<T> Corners<T>
1798where
1799 T: Clone + Default + Debug,
1800{
1801 /// Constructs `Corners` where all sides are set to the same specified value.
1802 ///
1803 /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1804 /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1805 /// such as a uniform border radius on a rectangle.
1806 ///
1807 /// # Arguments
1808 ///
1809 /// * `value` - The value to set for all four corners.
1810 ///
1811 /// # Returns
1812 ///
1813 /// An `Corners` instance with all corners set to the given value.
1814 ///
1815 /// # Examples
1816 ///
1817 /// ```
1818 /// # use zed::Corners;
1819 /// let uniform_corners = Corners::all(5.0);
1820 /// assert_eq!(uniform_corners.top_left, 5.0);
1821 /// assert_eq!(uniform_corners.top_right, 5.0);
1822 /// assert_eq!(uniform_corners.bottom_right, 5.0);
1823 /// assert_eq!(uniform_corners.bottom_left, 5.0);
1824 /// ```
1825 pub fn all(value: T) -> Self {
1826 Self {
1827 top_left: value.clone(),
1828 top_right: value.clone(),
1829 bottom_right: value.clone(),
1830 bottom_left: value,
1831 }
1832 }
1833}
1834
1835impl Corners<AbsoluteLength> {
1836 /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1837 /// `Pixels` do not exceed half of the maximum of the provided size's width and height.
1838 ///
1839 /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1840 /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1841 ///
1842 /// # Arguments
1843 ///
1844 /// * `size` - The `Size<Pixels>` against which the maximum allowable radius is determined.
1845 /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1846 ///
1847 /// # Returns
1848 ///
1849 /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1850 /// maximum allowable radius based on the provided size.
1851 ///
1852 /// # Examples
1853 ///
1854 /// ```
1855 /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1856 /// let corners = Corners {
1857 /// top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1858 /// top_right: AbsoluteLength::Rems(Rems(1.0)),
1859 /// bottom_right: AbsoluteLength::Pixels(Pixels(20.0)),
1860 /// bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1861 /// };
1862 /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1863 /// let rem_size = Pixels(16.0);
1864 /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1865 ///
1866 /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1867 /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1868 /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1869 /// assert_eq!(corners_in_pixels.bottom_right, Pixels(20.0).min(Pixels(25.0))); // Clamped to 25.0
1870 /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped
1871 /// ```
1872 pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1873 let max = size.width.max(size.height) / 2.;
1874 Corners {
1875 top_left: self.top_left.to_pixels(rem_size).min(max),
1876 top_right: self.top_right.to_pixels(rem_size).min(max),
1877 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1878 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1879 }
1880 }
1881}
1882
1883impl Corners<Pixels> {
1884 /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1885 ///
1886 /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1887 ///
1888 /// # Arguments
1889 ///
1890 /// * `factor` - The scaling factor to apply to each corner.
1891 ///
1892 /// # Returns
1893 ///
1894 /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1895 ///
1896 /// # Examples
1897 ///
1898 /// ```
1899 /// # use zed::{Corners, Pixels};
1900 /// let corners = Corners {
1901 /// top_left: Pixels(10.0),
1902 /// top_right: Pixels(20.0),
1903 /// bottom_right: Pixels(30.0),
1904 /// bottom_left: Pixels(40.0),
1905 /// };
1906 /// let scaled_corners = corners.scale(2.0);
1907 /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1908 /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1909 /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1910 /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1911 /// ```
1912 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1913 Corners {
1914 top_left: self.top_left.scale(factor),
1915 top_right: self.top_right.scale(factor),
1916 bottom_right: self.bottom_right.scale(factor),
1917 bottom_left: self.bottom_left.scale(factor),
1918 }
1919 }
1920
1921 /// Returns the maximum value of any corner.
1922 ///
1923 /// # Returns
1924 ///
1925 /// The maximum `Pixels` value among all four corners.
1926 pub fn max(&self) -> Pixels {
1927 self.top_left
1928 .max(self.top_right)
1929 .max(self.bottom_right)
1930 .max(self.bottom_left)
1931 }
1932}
1933
1934impl<T: Clone + Default + Debug> Corners<T> {
1935 /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
1936 ///
1937 /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
1938 /// that defines how to convert between the two types. The closure is applied to each field
1939 /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
1940 ///
1941 /// # Arguments
1942 ///
1943 /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1944 ///
1945 /// # Returns
1946 ///
1947 /// Returns a new `Corners<U>` with each field mapped by the provided function.
1948 ///
1949 /// # Examples
1950 ///
1951 /// ```
1952 /// # use zed::{Corners, Pixels};
1953 /// let corners = Corners {
1954 /// top_left: Pixels(10.0),
1955 /// top_right: Pixels(20.0),
1956 /// bottom_right: Pixels(30.0),
1957 /// bottom_left: Pixels(40.0),
1958 /// };
1959 /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
1960 /// assert_eq!(corners_in_rems, Corners {
1961 /// top_left: Rems(0.625),
1962 /// top_right: Rems(1.25),
1963 /// bottom_right: Rems(1.875),
1964 /// bottom_left: Rems(2.5),
1965 /// });
1966 /// ```
1967 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
1968 where
1969 U: Clone + Default + Debug,
1970 {
1971 Corners {
1972 top_left: f(&self.top_left),
1973 top_right: f(&self.top_right),
1974 bottom_right: f(&self.bottom_right),
1975 bottom_left: f(&self.bottom_left),
1976 }
1977 }
1978}
1979
1980impl<T> Mul for Corners<T>
1981where
1982 T: Mul<Output = T> + Clone + Default + Debug,
1983{
1984 type Output = Self;
1985
1986 fn mul(self, rhs: Self) -> Self::Output {
1987 Self {
1988 top_left: self.top_left.clone() * rhs.top_left,
1989 top_right: self.top_right.clone() * rhs.top_right,
1990 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
1991 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
1992 }
1993 }
1994}
1995
1996impl<T, S> MulAssign<S> for Corners<T>
1997where
1998 T: Mul<S, Output = T> + Clone + Default + Debug,
1999 S: Clone,
2000{
2001 fn mul_assign(&mut self, rhs: S) {
2002 self.top_left = self.top_left.clone() * rhs.clone();
2003 self.top_right = self.top_right.clone() * rhs.clone();
2004 self.bottom_right = self.bottom_right.clone() * rhs.clone();
2005 self.bottom_left = self.bottom_left.clone() * rhs;
2006 }
2007}
2008
2009impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
2010
2011impl From<f32> for Corners<Pixels> {
2012 fn from(val: f32) -> Self {
2013 Corners {
2014 top_left: val.into(),
2015 top_right: val.into(),
2016 bottom_right: val.into(),
2017 bottom_left: val.into(),
2018 }
2019 }
2020}
2021
2022impl From<Pixels> for Corners<Pixels> {
2023 fn from(val: Pixels) -> Self {
2024 Corners {
2025 top_left: val,
2026 top_right: val,
2027 bottom_right: val,
2028 bottom_left: val,
2029 }
2030 }
2031}
2032
2033/// Represents an angle in Radians
2034#[derive(
2035 Clone,
2036 Copy,
2037 Default,
2038 Add,
2039 AddAssign,
2040 Sub,
2041 SubAssign,
2042 Neg,
2043 Div,
2044 DivAssign,
2045 PartialEq,
2046 Serialize,
2047 Deserialize,
2048 Debug,
2049)]
2050#[repr(transparent)]
2051pub struct Radians(pub f32);
2052
2053/// Create a `Radian` from a raw value
2054pub fn radians(value: f32) -> Radians {
2055 Radians(value)
2056}
2057
2058/// A type representing a percentage value.
2059#[derive(
2060 Clone,
2061 Copy,
2062 Default,
2063 Add,
2064 AddAssign,
2065 Sub,
2066 SubAssign,
2067 Neg,
2068 Div,
2069 DivAssign,
2070 PartialEq,
2071 Serialize,
2072 Deserialize,
2073 Debug,
2074)]
2075#[repr(transparent)]
2076pub struct Percentage(pub f32);
2077
2078/// Generate a `Radian` from a percentage of a full circle.
2079pub fn percentage(value: f32) -> Percentage {
2080 debug_assert!(
2081 value >= 0.0 && value <= 1.0,
2082 "Percentage must be between 0 and 1"
2083 );
2084 Percentage(value)
2085}
2086
2087impl From<Percentage> for Radians {
2088 fn from(value: Percentage) -> Self {
2089 radians(value.0 * std::f32::consts::PI * 2.0)
2090 }
2091}
2092
2093/// Represents a length in pixels, the base unit of measurement in the UI framework.
2094///
2095/// `Pixels` is a value type that represents an absolute length in pixels, which is used
2096/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
2097/// of measurement for all visual elements and layout calculations.
2098///
2099/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
2100/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
2101/// is typically rounded to the nearest integer.
2102///
2103/// # Examples
2104///
2105/// ```
2106/// use zed::Pixels;
2107///
2108/// // Define a length of 10 pixels
2109/// let length = Pixels(10.0);
2110///
2111/// // Define a length and scale it by a factor of 2
2112/// let scaled_length = length.scale(2.0);
2113/// assert_eq!(scaled_length, Pixels(20.0));
2114/// ```
2115#[derive(
2116 Clone,
2117 Copy,
2118 Default,
2119 Add,
2120 AddAssign,
2121 Sub,
2122 SubAssign,
2123 Neg,
2124 Div,
2125 DivAssign,
2126 PartialEq,
2127 Serialize,
2128 Deserialize,
2129)]
2130#[repr(transparent)]
2131pub struct Pixels(pub f32);
2132
2133impl std::ops::Div for Pixels {
2134 type Output = f32;
2135
2136 fn div(self, rhs: Self) -> Self::Output {
2137 self.0 / rhs.0
2138 }
2139}
2140
2141impl std::ops::DivAssign for Pixels {
2142 fn div_assign(&mut self, rhs: Self) {
2143 *self = Self(self.0 / rhs.0);
2144 }
2145}
2146
2147impl std::ops::RemAssign for Pixels {
2148 fn rem_assign(&mut self, rhs: Self) {
2149 self.0 %= rhs.0;
2150 }
2151}
2152
2153impl std::ops::Rem for Pixels {
2154 type Output = Self;
2155
2156 fn rem(self, rhs: Self) -> Self {
2157 Self(self.0 % rhs.0)
2158 }
2159}
2160
2161impl Mul<f32> for Pixels {
2162 type Output = Pixels;
2163
2164 fn mul(self, other: f32) -> Pixels {
2165 Pixels(self.0 * other)
2166 }
2167}
2168
2169impl Mul<usize> for Pixels {
2170 type Output = Pixels;
2171
2172 fn mul(self, other: usize) -> Pixels {
2173 Pixels(self.0 * other as f32)
2174 }
2175}
2176
2177impl Mul<Pixels> for f32 {
2178 type Output = Pixels;
2179
2180 fn mul(self, rhs: Pixels) -> Self::Output {
2181 Pixels(self * rhs.0)
2182 }
2183}
2184
2185impl MulAssign<f32> for Pixels {
2186 fn mul_assign(&mut self, other: f32) {
2187 self.0 *= other;
2188 }
2189}
2190
2191impl Pixels {
2192 /// Represents zero pixels.
2193 pub const ZERO: Pixels = Pixels(0.0);
2194 /// The maximum value that can be represented by `Pixels`.
2195 pub const MAX: Pixels = Pixels(f32::MAX);
2196
2197 /// Floors the `Pixels` value to the nearest whole number.
2198 ///
2199 /// # Returns
2200 ///
2201 /// Returns a new `Pixels` instance with the floored value.
2202 pub fn floor(&self) -> Self {
2203 Self(self.0.floor())
2204 }
2205
2206 /// Rounds the `Pixels` value to the nearest whole number.
2207 ///
2208 /// # Returns
2209 ///
2210 /// Returns a new `Pixels` instance with the rounded value.
2211 pub fn round(&self) -> Self {
2212 Self(self.0.round())
2213 }
2214
2215 /// Returns the ceiling of the `Pixels` value to the nearest whole number.
2216 ///
2217 /// # Returns
2218 ///
2219 /// Returns a new `Pixels` instance with the ceiling value.
2220 pub fn ceil(&self) -> Self {
2221 Self(self.0.ceil())
2222 }
2223
2224 /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2225 ///
2226 /// This method is used when adjusting pixel values for display scaling factors,
2227 /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2228 /// thus requires scaling to maintain visual consistency and readability.
2229 ///
2230 /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2231 /// calculations where display scaling is considered.
2232 pub fn scale(&self, factor: f32) -> ScaledPixels {
2233 ScaledPixels(self.0 * factor)
2234 }
2235
2236 /// Raises the `Pixels` value to a given power.
2237 ///
2238 /// # Arguments
2239 ///
2240 /// * `exponent` - The exponent to raise the `Pixels` value by.
2241 ///
2242 /// # Returns
2243 ///
2244 /// Returns a new `Pixels` instance with the value raised to the given exponent.
2245 pub fn pow(&self, exponent: f32) -> Self {
2246 Self(self.0.powf(exponent))
2247 }
2248
2249 /// Returns the absolute value of the `Pixels`.
2250 ///
2251 /// # Returns
2252 ///
2253 /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2254 pub fn abs(&self) -> Self {
2255 Self(self.0.abs())
2256 }
2257}
2258
2259impl Mul<Pixels> for Pixels {
2260 type Output = Pixels;
2261
2262 fn mul(self, rhs: Pixels) -> Self::Output {
2263 Pixels(self.0 * rhs.0)
2264 }
2265}
2266
2267impl Eq for Pixels {}
2268
2269impl PartialOrd for Pixels {
2270 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2271 Some(self.cmp(other))
2272 }
2273}
2274
2275impl Ord for Pixels {
2276 fn cmp(&self, other: &Self) -> cmp::Ordering {
2277 self.0.total_cmp(&other.0)
2278 }
2279}
2280
2281impl std::hash::Hash for Pixels {
2282 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2283 self.0.to_bits().hash(state);
2284 }
2285}
2286
2287impl From<f64> for Pixels {
2288 fn from(pixels: f64) -> Self {
2289 Pixels(pixels as f32)
2290 }
2291}
2292
2293impl From<f32> for Pixels {
2294 fn from(pixels: f32) -> Self {
2295 Pixels(pixels)
2296 }
2297}
2298
2299impl Debug for Pixels {
2300 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2301 write!(f, "{} px", self.0)
2302 }
2303}
2304
2305impl From<Pixels> for f32 {
2306 fn from(pixels: Pixels) -> Self {
2307 pixels.0
2308 }
2309}
2310
2311impl From<&Pixels> for f32 {
2312 fn from(pixels: &Pixels) -> Self {
2313 pixels.0
2314 }
2315}
2316
2317impl From<Pixels> for f64 {
2318 fn from(pixels: Pixels) -> Self {
2319 pixels.0 as f64
2320 }
2321}
2322
2323impl From<Pixels> for u32 {
2324 fn from(pixels: Pixels) -> Self {
2325 pixels.0 as u32
2326 }
2327}
2328
2329impl From<u32> for Pixels {
2330 fn from(pixels: u32) -> Self {
2331 Pixels(pixels as f32)
2332 }
2333}
2334
2335impl From<Pixels> for usize {
2336 fn from(pixels: Pixels) -> Self {
2337 pixels.0 as usize
2338 }
2339}
2340
2341impl From<usize> for Pixels {
2342 fn from(pixels: usize) -> Self {
2343 Pixels(pixels as f32)
2344 }
2345}
2346
2347/// Represents physical pixels on the display.
2348///
2349/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2350/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2351/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2352/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2353/// display.
2354#[derive(
2355 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
2356)]
2357#[repr(transparent)]
2358pub struct DevicePixels(pub(crate) i32);
2359
2360impl DevicePixels {
2361 /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2362 ///
2363 /// This function is useful when working with graphical data that needs to be stored in a buffer,
2364 /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2365 ///
2366 /// # Arguments
2367 ///
2368 /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2369 ///
2370 /// # Returns
2371 ///
2372 /// The number of bytes required to represent the `DevicePixels` value in memory.
2373 ///
2374 /// # Examples
2375 ///
2376 /// ```
2377 /// # use zed::DevicePixels;
2378 /// let pixels = DevicePixels(10); // 10 device pixels
2379 /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2380 /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2381 /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2382 /// ```
2383 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2384 self.0 as u32 * bytes_per_pixel as u32
2385 }
2386}
2387
2388impl fmt::Debug for DevicePixels {
2389 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2390 write!(f, "{} px (device)", self.0)
2391 }
2392}
2393
2394impl From<DevicePixels> for i32 {
2395 fn from(device_pixels: DevicePixels) -> Self {
2396 device_pixels.0
2397 }
2398}
2399
2400impl From<i32> for DevicePixels {
2401 fn from(device_pixels: i32) -> Self {
2402 DevicePixels(device_pixels)
2403 }
2404}
2405
2406impl From<u32> for DevicePixels {
2407 fn from(device_pixels: u32) -> Self {
2408 DevicePixels(device_pixels as i32)
2409 }
2410}
2411
2412impl From<DevicePixels> for u32 {
2413 fn from(device_pixels: DevicePixels) -> Self {
2414 device_pixels.0 as u32
2415 }
2416}
2417
2418impl From<DevicePixels> for u64 {
2419 fn from(device_pixels: DevicePixels) -> Self {
2420 device_pixels.0 as u64
2421 }
2422}
2423
2424impl From<u64> for DevicePixels {
2425 fn from(device_pixels: u64) -> Self {
2426 DevicePixels(device_pixels as i32)
2427 }
2428}
2429
2430impl From<DevicePixels> for usize {
2431 fn from(device_pixels: DevicePixels) -> Self {
2432 device_pixels.0 as usize
2433 }
2434}
2435
2436impl From<usize> for DevicePixels {
2437 fn from(device_pixels: usize) -> Self {
2438 DevicePixels(device_pixels as i32)
2439 }
2440}
2441
2442/// Represents scaled pixels that take into account the device's scale factor.
2443///
2444/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2445/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2446/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2447/// dimensions and positions can be specified in a way that scales appropriately across different
2448/// display resolutions.
2449#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2450#[repr(transparent)]
2451pub struct ScaledPixels(pub(crate) f32);
2452
2453impl ScaledPixels {
2454 /// Floors the `ScaledPixels` value to the nearest whole number.
2455 ///
2456 /// # Returns
2457 ///
2458 /// Returns a new `ScaledPixels` instance with the floored value.
2459 pub fn floor(&self) -> Self {
2460 Self(self.0.floor())
2461 }
2462
2463 /// Rounds the `ScaledPixels` value to the nearest whole number.
2464 ///
2465 /// # Returns
2466 ///
2467 /// Returns a new `ScaledPixels` instance with the rounded value.
2468 pub fn ceil(&self) -> Self {
2469 Self(self.0.ceil())
2470 }
2471}
2472
2473impl Eq for ScaledPixels {}
2474
2475impl Debug for ScaledPixels {
2476 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2477 write!(f, "{} px (scaled)", self.0)
2478 }
2479}
2480
2481impl From<ScaledPixels> for DevicePixels {
2482 fn from(scaled: ScaledPixels) -> Self {
2483 DevicePixels(scaled.0.ceil() as i32)
2484 }
2485}
2486
2487impl From<DevicePixels> for ScaledPixels {
2488 fn from(device: DevicePixels) -> Self {
2489 ScaledPixels(device.0 as f32)
2490 }
2491}
2492
2493impl From<ScaledPixels> for f64 {
2494 fn from(scaled_pixels: ScaledPixels) -> Self {
2495 scaled_pixels.0 as f64
2496 }
2497}
2498
2499/// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`WindowContext::set_rem_size`][set_rem_size].
2500///
2501/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2502/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2503/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2504/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2505///
2506/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2507///
2508/// [set_rem_size]: crate::WindowContext::set_rem_size
2509#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2510pub struct Rems(pub f32);
2511
2512impl Rems {
2513 /// Convert this Rem value to pixels.
2514 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2515 *self * rem_size
2516 }
2517}
2518
2519impl Mul<Pixels> for Rems {
2520 type Output = Pixels;
2521
2522 fn mul(self, other: Pixels) -> Pixels {
2523 Pixels(self.0 * other.0)
2524 }
2525}
2526
2527impl Debug for Rems {
2528 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2529 write!(f, "{} rem", self.0)
2530 }
2531}
2532
2533/// Represents an absolute length in pixels or rems.
2534///
2535/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2536/// affected by the current font size, or a number of rems, which is relative to the font size of
2537/// the root element. It is used for specifying dimensions that are either independent of or
2538/// related to the typographic scale.
2539#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2540pub enum AbsoluteLength {
2541 /// A length in pixels.
2542 Pixels(Pixels),
2543 /// A length in rems.
2544 Rems(Rems),
2545}
2546
2547impl AbsoluteLength {
2548 /// Checks if the absolute length is zero.
2549 pub fn is_zero(&self) -> bool {
2550 match self {
2551 AbsoluteLength::Pixels(px) => px.0 == 0.0,
2552 AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2553 }
2554 }
2555}
2556
2557impl From<Pixels> for AbsoluteLength {
2558 fn from(pixels: Pixels) -> Self {
2559 AbsoluteLength::Pixels(pixels)
2560 }
2561}
2562
2563impl From<Rems> for AbsoluteLength {
2564 fn from(rems: Rems) -> Self {
2565 AbsoluteLength::Rems(rems)
2566 }
2567}
2568
2569impl AbsoluteLength {
2570 /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2571 ///
2572 /// # Arguments
2573 ///
2574 /// * `rem_size` - The size of one rem in pixels.
2575 ///
2576 /// # Returns
2577 ///
2578 /// Returns the `AbsoluteLength` as `Pixels`.
2579 ///
2580 /// # Examples
2581 ///
2582 /// ```
2583 /// # use zed::{AbsoluteLength, Pixels};
2584 /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2585 /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2586 /// let rem_size = Pixels(16.0);
2587 ///
2588 /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2589 /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2590 /// ```
2591 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2592 match self {
2593 AbsoluteLength::Pixels(pixels) => *pixels,
2594 AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size),
2595 }
2596 }
2597}
2598
2599impl Default for AbsoluteLength {
2600 fn default() -> Self {
2601 px(0.).into()
2602 }
2603}
2604
2605/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2606///
2607/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2608/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2609/// fraction of the parent's size.
2610#[derive(Clone, Copy, Neg, PartialEq)]
2611pub enum DefiniteLength {
2612 /// An absolute length specified in pixels or rems.
2613 Absolute(AbsoluteLength),
2614 /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2615 Fraction(f32),
2616}
2617
2618impl DefiniteLength {
2619 /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2620 ///
2621 /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2622 /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2623 ///
2624 /// # Arguments
2625 ///
2626 /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2627 /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2628 ///
2629 /// # Returns
2630 ///
2631 /// Returns the `DefiniteLength` as `Pixels`.
2632 ///
2633 /// # Examples
2634 ///
2635 /// ```
2636 /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2637 /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2638 /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2639 /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2640 /// let base_size = AbsoluteLength::Pixels(px(100.0));
2641 /// let rem_size = px(16.0);
2642 ///
2643 /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2644 /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2645 /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2646 /// ```
2647 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2648 match self {
2649 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2650 DefiniteLength::Fraction(fraction) => match base_size {
2651 AbsoluteLength::Pixels(px) => px * *fraction,
2652 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2653 },
2654 }
2655 }
2656}
2657
2658impl Debug for DefiniteLength {
2659 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2660 match self {
2661 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2662 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2663 }
2664 }
2665}
2666
2667impl From<Pixels> for DefiniteLength {
2668 fn from(pixels: Pixels) -> Self {
2669 Self::Absolute(pixels.into())
2670 }
2671}
2672
2673impl From<Rems> for DefiniteLength {
2674 fn from(rems: Rems) -> Self {
2675 Self::Absolute(rems.into())
2676 }
2677}
2678
2679impl From<AbsoluteLength> for DefiniteLength {
2680 fn from(length: AbsoluteLength) -> Self {
2681 Self::Absolute(length)
2682 }
2683}
2684
2685impl Default for DefiniteLength {
2686 fn default() -> Self {
2687 Self::Absolute(AbsoluteLength::default())
2688 }
2689}
2690
2691/// A length that can be defined in pixels, rems, percent of parent, or auto.
2692#[derive(Clone, Copy)]
2693pub enum Length {
2694 /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2695 Definite(DefiniteLength),
2696 /// An automatic length that is determined by the context in which it is used.
2697 Auto,
2698}
2699
2700impl Debug for Length {
2701 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2702 match self {
2703 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2704 Length::Auto => write!(f, "auto"),
2705 }
2706 }
2707}
2708
2709/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2710///
2711/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2712/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2713///
2714/// # Arguments
2715///
2716/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2717///
2718/// # Returns
2719///
2720/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2721pub fn relative(fraction: f32) -> DefiniteLength {
2722 DefiniteLength::Fraction(fraction)
2723}
2724
2725/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2726pub fn phi() -> DefiniteLength {
2727 relative(1.618_034)
2728}
2729
2730/// Constructs a `Rems` value representing a length in rems.
2731///
2732/// # Arguments
2733///
2734/// * `rems` - The number of rems for the length.
2735///
2736/// # Returns
2737///
2738/// A `Rems` representing the specified number of rems.
2739pub fn rems(rems: f32) -> Rems {
2740 Rems(rems)
2741}
2742
2743/// Constructs a `Pixels` value representing a length in pixels.
2744///
2745/// # Arguments
2746///
2747/// * `pixels` - The number of pixels for the length.
2748///
2749/// # Returns
2750///
2751/// A `Pixels` representing the specified number of pixels.
2752pub const fn px(pixels: f32) -> Pixels {
2753 Pixels(pixels)
2754}
2755
2756/// Returns a `Length` representing an automatic length.
2757///
2758/// The `auto` length is often used in layout calculations where the length should be determined
2759/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2760/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2761/// to instruct the layout engine to calculate the size based on other factors like the size of the
2762/// container or the intrinsic size of the content.
2763///
2764/// # Returns
2765///
2766/// A `Length` variant set to `Auto`.
2767pub fn auto() -> Length {
2768 Length::Auto
2769}
2770
2771impl From<Pixels> for Length {
2772 fn from(pixels: Pixels) -> Self {
2773 Self::Definite(pixels.into())
2774 }
2775}
2776
2777impl From<Rems> for Length {
2778 fn from(rems: Rems) -> Self {
2779 Self::Definite(rems.into())
2780 }
2781}
2782
2783impl From<DefiniteLength> for Length {
2784 fn from(length: DefiniteLength) -> Self {
2785 Self::Definite(length)
2786 }
2787}
2788
2789impl From<AbsoluteLength> for Length {
2790 fn from(length: AbsoluteLength) -> Self {
2791 Self::Definite(length.into())
2792 }
2793}
2794
2795impl Default for Length {
2796 fn default() -> Self {
2797 Self::Definite(DefiniteLength::default())
2798 }
2799}
2800
2801impl From<()> for Length {
2802 fn from(_: ()) -> Self {
2803 Self::Definite(DefiniteLength::default())
2804 }
2805}
2806
2807/// Provides a trait for types that can calculate half of their value.
2808///
2809/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2810/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2811/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2812pub trait Half {
2813 /// Returns half of the current value.
2814 ///
2815 /// # Returns
2816 ///
2817 /// A new instance of the implementing type, representing half of the original value.
2818 fn half(&self) -> Self;
2819}
2820
2821impl Half for i32 {
2822 fn half(&self) -> Self {
2823 self / 2
2824 }
2825}
2826
2827impl Half for f32 {
2828 fn half(&self) -> Self {
2829 self / 2.
2830 }
2831}
2832
2833impl Half for DevicePixels {
2834 fn half(&self) -> Self {
2835 Self(self.0 / 2)
2836 }
2837}
2838
2839impl Half for ScaledPixels {
2840 fn half(&self) -> Self {
2841 Self(self.0 / 2.)
2842 }
2843}
2844
2845impl Half for Pixels {
2846 fn half(&self) -> Self {
2847 Self(self.0 / 2.)
2848 }
2849}
2850
2851impl Half for Rems {
2852 fn half(&self) -> Self {
2853 Self(self.0 / 2.)
2854 }
2855}
2856
2857/// Provides a trait for types that can negate their values.
2858pub trait Negate {
2859 /// Returns the negation of the given value
2860 fn negate(self) -> Self;
2861}
2862
2863impl Negate for i32 {
2864 fn negate(self) -> Self {
2865 -self
2866 }
2867}
2868
2869impl Negate for f32 {
2870 fn negate(self) -> Self {
2871 -self
2872 }
2873}
2874
2875impl Negate for DevicePixels {
2876 fn negate(self) -> Self {
2877 Self(-self.0)
2878 }
2879}
2880
2881impl Negate for ScaledPixels {
2882 fn negate(self) -> Self {
2883 Self(-self.0)
2884 }
2885}
2886
2887impl Negate for Pixels {
2888 fn negate(self) -> Self {
2889 Self(-self.0)
2890 }
2891}
2892
2893impl Negate for Rems {
2894 fn negate(self) -> Self {
2895 Self(-self.0)
2896 }
2897}
2898
2899/// A trait for checking if a value is zero.
2900///
2901/// This trait provides a method to determine if a value is considered to be zero.
2902/// It is implemented for various numeric and length-related types where the concept
2903/// of zero is applicable. This can be useful for comparisons, optimizations, or
2904/// determining if an operation has a neutral effect.
2905pub trait IsZero {
2906 /// Determines if the value is zero.
2907 ///
2908 /// # Returns
2909 ///
2910 /// Returns `true` if the value is zero, `false` otherwise.
2911 fn is_zero(&self) -> bool;
2912}
2913
2914impl IsZero for DevicePixels {
2915 fn is_zero(&self) -> bool {
2916 self.0 == 0
2917 }
2918}
2919
2920impl IsZero for ScaledPixels {
2921 fn is_zero(&self) -> bool {
2922 self.0 == 0.
2923 }
2924}
2925
2926impl IsZero for Pixels {
2927 fn is_zero(&self) -> bool {
2928 self.0 == 0.
2929 }
2930}
2931
2932impl IsZero for Rems {
2933 fn is_zero(&self) -> bool {
2934 self.0 == 0.
2935 }
2936}
2937
2938impl IsZero for AbsoluteLength {
2939 fn is_zero(&self) -> bool {
2940 match self {
2941 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
2942 AbsoluteLength::Rems(rems) => rems.is_zero(),
2943 }
2944 }
2945}
2946
2947impl IsZero for DefiniteLength {
2948 fn is_zero(&self) -> bool {
2949 match self {
2950 DefiniteLength::Absolute(length) => length.is_zero(),
2951 DefiniteLength::Fraction(fraction) => *fraction == 0.,
2952 }
2953 }
2954}
2955
2956impl IsZero for Length {
2957 fn is_zero(&self) -> bool {
2958 match self {
2959 Length::Definite(length) => length.is_zero(),
2960 Length::Auto => false,
2961 }
2962 }
2963}
2964
2965impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
2966 fn is_zero(&self) -> bool {
2967 self.x.is_zero() && self.y.is_zero()
2968 }
2969}
2970
2971impl<T> IsZero for Size<T>
2972where
2973 T: IsZero + Default + Debug + Clone,
2974{
2975 fn is_zero(&self) -> bool {
2976 self.width.is_zero() || self.height.is_zero()
2977 }
2978}
2979
2980impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
2981 fn is_zero(&self) -> bool {
2982 self.size.is_zero()
2983 }
2984}
2985
2986impl<T> IsZero for Corners<T>
2987where
2988 T: IsZero + Clone + Default + Debug,
2989{
2990 fn is_zero(&self) -> bool {
2991 self.top_left.is_zero()
2992 && self.top_right.is_zero()
2993 && self.bottom_right.is_zero()
2994 && self.bottom_left.is_zero()
2995 }
2996}
2997
2998#[cfg(test)]
2999mod tests {
3000 use super::*;
3001
3002 #[test]
3003 fn test_bounds_intersects() {
3004 let bounds1 = Bounds {
3005 origin: Point { x: 0.0, y: 0.0 },
3006 size: Size {
3007 width: 5.0,
3008 height: 5.0,
3009 },
3010 };
3011 let bounds2 = Bounds {
3012 origin: Point { x: 4.0, y: 4.0 },
3013 size: Size {
3014 width: 5.0,
3015 height: 5.0,
3016 },
3017 };
3018 let bounds3 = Bounds {
3019 origin: Point { x: 10.0, y: 10.0 },
3020 size: Size {
3021 width: 5.0,
3022 height: 5.0,
3023 },
3024 };
3025
3026 // Test Case 1: Intersecting bounds
3027 assert_eq!(bounds1.intersects(&bounds2), true);
3028
3029 // Test Case 2: Non-Intersecting bounds
3030 assert_eq!(bounds1.intersects(&bounds3), false);
3031
3032 // Test Case 3: Bounds intersecting with themselves
3033 assert_eq!(bounds1.intersects(&bounds1), true);
3034 }
3035}