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