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
833impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
834 /// Calculates the intersection of two `Bounds` objects.
835 ///
836 /// This method computes the overlapping region of two `Bounds`. If the bounds do not intersect,
837 /// the resulting `Bounds` will have a size with width and height of zero.
838 ///
839 /// # Arguments
840 ///
841 /// * `other` - A reference to another `Bounds` to intersect with.
842 ///
843 /// # Returns
844 ///
845 /// Returns a `Bounds` representing the intersection area. If there is no intersection,
846 /// the returned `Bounds` will have a size with width and height of zero.
847 ///
848 /// # Examples
849 ///
850 /// ```
851 /// # use zed::{Bounds, Point, Size};
852 /// let bounds1 = Bounds {
853 /// origin: Point { x: 0, y: 0 },
854 /// size: Size { width: 10, height: 10 },
855 /// };
856 /// let bounds2 = Bounds {
857 /// origin: Point { x: 5, y: 5 },
858 /// size: Size { width: 10, height: 10 },
859 /// };
860 /// let intersection = bounds1.intersect(&bounds2);
861 ///
862 /// assert_eq!(intersection, Bounds {
863 /// origin: Point { x: 5, y: 5 },
864 /// size: Size { width: 5, height: 5 },
865 /// });
866 /// ```
867 pub fn intersect(&self, other: &Self) -> Self {
868 let upper_left = self.origin.max(&other.origin);
869 let lower_right = self.lower_right().min(&other.lower_right());
870 Self::from_corners(upper_left, lower_right)
871 }
872
873 /// Computes the union of two `Bounds`.
874 ///
875 /// This method calculates the smallest `Bounds` that contains both the current `Bounds` and the `other` `Bounds`.
876 /// The resulting `Bounds` will have an origin that is the minimum of the origins of the two `Bounds`,
877 /// and a size that encompasses the furthest extents of both `Bounds`.
878 ///
879 /// # Arguments
880 ///
881 /// * `other` - A reference to another `Bounds` to create a union with.
882 ///
883 /// # Returns
884 ///
885 /// Returns a `Bounds` representing the union of the two `Bounds`.
886 ///
887 /// # Examples
888 ///
889 /// ```
890 /// # use zed::{Bounds, Point, Size};
891 /// let bounds1 = Bounds {
892 /// origin: Point { x: 0, y: 0 },
893 /// size: Size { width: 10, height: 10 },
894 /// };
895 /// let bounds2 = Bounds {
896 /// origin: Point { x: 5, y: 5 },
897 /// size: Size { width: 15, height: 15 },
898 /// };
899 /// let union_bounds = bounds1.union(&bounds2);
900 ///
901 /// assert_eq!(union_bounds, Bounds {
902 /// origin: Point { x: 0, y: 0 },
903 /// size: Size { width: 20, height: 20 },
904 /// });
905 /// ```
906 pub fn union(&self, other: &Self) -> Self {
907 let top_left = self.origin.min(&other.origin);
908 let bottom_right = self.lower_right().max(&other.lower_right());
909 Bounds::from_corners(top_left, bottom_right)
910 }
911}
912
913impl<T, Rhs> Mul<Rhs> for Bounds<T>
914where
915 T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
916 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
917 Rhs: Clone + Default + Debug,
918{
919 type Output = Bounds<Rhs>;
920
921 fn mul(self, rhs: Rhs) -> Self::Output {
922 Bounds {
923 origin: self.origin * rhs.clone(),
924 size: self.size * rhs,
925 }
926 }
927}
928
929impl<T, S> MulAssign<S> for Bounds<T>
930where
931 T: Mul<S, Output = T> + Clone + Default + Debug,
932 S: Clone,
933{
934 fn mul_assign(&mut self, rhs: S) {
935 self.origin *= rhs.clone();
936 self.size *= rhs;
937 }
938}
939
940impl<T, S> Div<S> for Bounds<T>
941where
942 Size<T>: Div<S, Output = Size<T>>,
943 T: Div<S, Output = T> + Default + Clone + Debug,
944 S: Clone,
945{
946 type Output = Self;
947
948 fn div(self, rhs: S) -> Self {
949 Self {
950 origin: self.origin / rhs.clone(),
951 size: self.size / rhs,
952 }
953 }
954}
955
956impl<T> Bounds<T>
957where
958 T: Add<T, Output = T> + Clone + Default + Debug,
959{
960 /// Returns the top edge of the bounds.
961 ///
962 /// # Returns
963 ///
964 /// A value of type `T` representing the y-coordinate of the top edge of the bounds.
965 pub fn top(&self) -> T {
966 self.origin.y.clone()
967 }
968
969 /// Returns the bottom edge of the bounds.
970 ///
971 /// # Returns
972 ///
973 /// A value of type `T` representing the y-coordinate of the bottom edge of the bounds.
974 pub fn bottom(&self) -> T {
975 self.origin.y.clone() + self.size.height.clone()
976 }
977
978 /// Returns the left edge of the bounds.
979 ///
980 /// # Returns
981 ///
982 /// A value of type `T` representing the x-coordinate of the left edge of the bounds.
983 pub fn left(&self) -> T {
984 self.origin.x.clone()
985 }
986
987 /// Returns the right edge of the bounds.
988 ///
989 /// # Returns
990 ///
991 /// A value of type `T` representing the x-coordinate of the right edge of the bounds.
992 pub fn right(&self) -> T {
993 self.origin.x.clone() + self.size.width.clone()
994 }
995
996 /// Returns the upper-right corner point of the bounds.
997 ///
998 /// # Returns
999 ///
1000 /// A `Point<T>` representing the upper-right corner of the bounds.
1001 ///
1002 /// # Examples
1003 ///
1004 /// ```
1005 /// # use zed::{Bounds, Point, Size};
1006 /// let bounds = Bounds {
1007 /// origin: Point { x: 0, y: 0 },
1008 /// size: Size { width: 10, height: 20 },
1009 /// };
1010 /// let upper_right = bounds.upper_right();
1011 /// assert_eq!(upper_right, Point { x: 10, y: 0 });
1012 /// ```
1013 pub fn upper_right(&self) -> Point<T> {
1014 Point {
1015 x: self.origin.x.clone() + self.size.width.clone(),
1016 y: self.origin.y.clone(),
1017 }
1018 }
1019
1020 /// Returns the lower-right corner point of the bounds.
1021 ///
1022 /// # Returns
1023 ///
1024 /// A `Point<T>` representing the lower-right corner of the bounds.
1025 ///
1026 /// # Examples
1027 ///
1028 /// ```
1029 /// # use zed::{Bounds, Point, Size};
1030 /// let bounds = Bounds {
1031 /// origin: Point { x: 0, y: 0 },
1032 /// size: Size { width: 10, height: 20 },
1033 /// };
1034 /// let lower_right = bounds.lower_right();
1035 /// assert_eq!(lower_right, Point { x: 10, y: 20 });
1036 /// ```
1037 pub fn lower_right(&self) -> Point<T> {
1038 Point {
1039 x: self.origin.x.clone() + self.size.width.clone(),
1040 y: self.origin.y.clone() + self.size.height.clone(),
1041 }
1042 }
1043
1044 /// Returns the lower-left corner point of the bounds.
1045 ///
1046 /// # Returns
1047 ///
1048 /// A `Point<T>` representing the lower-left corner of the bounds.
1049 ///
1050 /// # Examples
1051 ///
1052 /// ```
1053 /// # use zed::{Bounds, Point, Size};
1054 /// let bounds = Bounds {
1055 /// origin: Point { x: 0, y: 0 },
1056 /// size: Size { width: 10, height: 20 },
1057 /// };
1058 /// let lower_left = bounds.lower_left();
1059 /// assert_eq!(lower_left, Point { x: 0, y: 20 });
1060 /// ```
1061 pub fn lower_left(&self) -> Point<T> {
1062 Point {
1063 x: self.origin.x.clone(),
1064 y: self.origin.y.clone() + self.size.height.clone(),
1065 }
1066 }
1067}
1068
1069impl<T> Bounds<T>
1070where
1071 T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
1072{
1073 /// Checks if the given point is within the bounds.
1074 ///
1075 /// This method determines whether a point lies inside the rectangle defined by the bounds,
1076 /// including the edges. The point is considered inside if its x-coordinate is greater than
1077 /// or equal to the left edge and less than or equal to the right edge, and its y-coordinate
1078 /// is greater than or equal to the top edge and less than or equal to the bottom edge of the bounds.
1079 ///
1080 /// # Arguments
1081 ///
1082 /// * `point` - A reference to a `Point<T>` that represents the point to check.
1083 ///
1084 /// # Returns
1085 ///
1086 /// Returns `true` if the point is within the bounds, `false` otherwise.
1087 ///
1088 /// # Examples
1089 ///
1090 /// ```
1091 /// # use zed::{Point, Bounds};
1092 /// let bounds = Bounds {
1093 /// origin: Point { x: 0, y: 0 },
1094 /// size: Size { width: 10, height: 10 },
1095 /// };
1096 /// let inside_point = Point { x: 5, y: 5 };
1097 /// let outside_point = Point { x: 15, y: 15 };
1098 ///
1099 /// assert!(bounds.contains_point(&inside_point));
1100 /// assert!(!bounds.contains_point(&outside_point));
1101 /// ```
1102 pub fn contains(&self, point: &Point<T>) -> bool {
1103 point.x >= self.origin.x
1104 && point.x <= self.origin.x.clone() + self.size.width.clone()
1105 && point.y >= self.origin.y
1106 && point.y <= self.origin.y.clone() + self.size.height.clone()
1107 }
1108
1109 /// Applies a function to the origin and size of the bounds, producing a new `Bounds<U>`.
1110 ///
1111 /// This method allows for converting a `Bounds<T>` to a `Bounds<U>` by specifying a closure
1112 /// that defines how to convert between the two types. The closure is applied to the `origin` and
1113 /// `size` fields, resulting in new bounds of the desired type.
1114 ///
1115 /// # Arguments
1116 ///
1117 /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
1118 ///
1119 /// # Returns
1120 ///
1121 /// Returns a new `Bounds<U>` with the origin and size mapped by the provided function.
1122 ///
1123 /// # Examples
1124 ///
1125 /// ```
1126 /// # use zed::{Bounds, Point, Size};
1127 /// let bounds = Bounds {
1128 /// origin: Point { x: 10.0, y: 10.0 },
1129 /// size: Size { width: 10.0, height: 20.0 },
1130 /// };
1131 /// let new_bounds = bounds.map(|value| value as f64 * 1.5);
1132 ///
1133 /// assert_eq!(new_bounds, Bounds {
1134 /// origin: Point { x: 15.0, y: 15.0 },
1135 /// size: Size { width: 15.0, height: 30.0 },
1136 /// });
1137 pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
1138 where
1139 U: Clone + Default + Debug,
1140 {
1141 Bounds {
1142 origin: self.origin.map(&f),
1143 size: self.size.map(f),
1144 }
1145 }
1146}
1147
1148impl Bounds<Pixels> {
1149 /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1150 ///
1151 /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1152 /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1153 /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1154 /// scaled for different display densities.
1155 ///
1156 /// # Arguments
1157 ///
1158 /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1159 ///
1160 /// # Returns
1161 ///
1162 /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1163 ///
1164 /// # Examples
1165 ///
1166 /// ```
1167 /// # use zed::{Bounds, Point, Size, Pixels};
1168 /// let bounds = Bounds {
1169 /// origin: Point { x: Pixels(10.0), y: Pixels(20.0) },
1170 /// size: Size { width: Pixels(30.0), height: Pixels(40.0) },
1171 /// };
1172 /// let display_scale_factor = 2.0;
1173 /// let scaled_bounds = bounds.scale(display_scale_factor);
1174 /// assert_eq!(scaled_bounds, Bounds {
1175 /// origin: Point { x: ScaledPixels(20.0), y: ScaledPixels(40.0) },
1176 /// size: Size { width: ScaledPixels(60.0), height: ScaledPixels(80.0) },
1177 /// });
1178 /// ```
1179 pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1180 Bounds {
1181 origin: self.origin.scale(factor),
1182 size: self.size.scale(factor),
1183 }
1184 }
1185}
1186
1187impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
1188
1189/// Represents the edges of a box in a 2D space, such as padding or margin.
1190///
1191/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1192///
1193/// # Examples
1194///
1195/// ```
1196/// # use zed::Edges;
1197/// let edges = Edges {
1198/// top: 10.0,
1199/// right: 20.0,
1200/// bottom: 30.0,
1201/// left: 40.0,
1202/// };
1203///
1204/// assert_eq!(edges.top, 10.0);
1205/// assert_eq!(edges.right, 20.0);
1206/// assert_eq!(edges.bottom, 30.0);
1207/// assert_eq!(edges.left, 40.0);
1208/// ```
1209#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1210#[refineable(Debug)]
1211#[repr(C)]
1212pub struct Edges<T: Clone + Default + Debug> {
1213 /// The size of the top edge.
1214 pub top: T,
1215 /// The size of the right edge.
1216 pub right: T,
1217 /// The size of the bottom edge.
1218 pub bottom: T,
1219 /// The size of the left edge.
1220 pub left: T,
1221}
1222
1223impl<T> Mul for Edges<T>
1224where
1225 T: Mul<Output = T> + Clone + Default + Debug,
1226{
1227 type Output = Self;
1228
1229 fn mul(self, rhs: Self) -> Self::Output {
1230 Self {
1231 top: self.top.clone() * rhs.top,
1232 right: self.right.clone() * rhs.right,
1233 bottom: self.bottom.clone() * rhs.bottom,
1234 left: self.left.clone() * rhs.left,
1235 }
1236 }
1237}
1238
1239impl<T, S> MulAssign<S> for Edges<T>
1240where
1241 T: Mul<S, Output = T> + Clone + Default + Debug,
1242 S: Clone,
1243{
1244 fn mul_assign(&mut self, rhs: S) {
1245 self.top = self.top.clone() * rhs.clone();
1246 self.right = self.right.clone() * rhs.clone();
1247 self.bottom = self.bottom.clone() * rhs.clone();
1248 self.left = self.left.clone() * rhs;
1249 }
1250}
1251
1252impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
1253
1254impl<T: Clone + Default + Debug> Edges<T> {
1255 /// Constructs `Edges` where all sides are set to the same specified value.
1256 ///
1257 /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1258 /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1259 /// such as padding or margin with the same size on all sides.
1260 ///
1261 /// # Arguments
1262 ///
1263 /// * `value` - The value to set for all four sides of the edges.
1264 ///
1265 /// # Returns
1266 ///
1267 /// An `Edges` instance with all sides set to the given value.
1268 ///
1269 /// # Examples
1270 ///
1271 /// ```
1272 /// # use zed::Edges;
1273 /// let uniform_edges = Edges::all(10.0);
1274 /// assert_eq!(uniform_edges.top, 10.0);
1275 /// assert_eq!(uniform_edges.right, 10.0);
1276 /// assert_eq!(uniform_edges.bottom, 10.0);
1277 /// assert_eq!(uniform_edges.left, 10.0);
1278 /// ```
1279 pub fn all(value: T) -> Self {
1280 Self {
1281 top: value.clone(),
1282 right: value.clone(),
1283 bottom: value.clone(),
1284 left: value,
1285 }
1286 }
1287
1288 /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1289 ///
1290 /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1291 /// that defines how to convert between the two types. The closure is applied to each field
1292 /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1293 ///
1294 /// # Arguments
1295 ///
1296 /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1297 ///
1298 /// # Returns
1299 ///
1300 /// Returns a new `Edges<U>` with each field mapped by the provided function.
1301 ///
1302 /// # Examples
1303 ///
1304 /// ```
1305 /// # use zed::Edges;
1306 /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1307 /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1308 /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1309 /// ```
1310 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1311 where
1312 U: Clone + Default + Debug,
1313 {
1314 Edges {
1315 top: f(&self.top),
1316 right: f(&self.right),
1317 bottom: f(&self.bottom),
1318 left: f(&self.left),
1319 }
1320 }
1321
1322 /// Checks if any of the edges satisfy a given predicate.
1323 ///
1324 /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1325 ///
1326 /// # Arguments
1327 ///
1328 /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1329 ///
1330 /// # Returns
1331 ///
1332 /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1333 ///
1334 /// # Examples
1335 ///
1336 /// ```
1337 /// # use zed::Edges;
1338 /// let edges = Edges {
1339 /// top: 10,
1340 /// right: 0,
1341 /// bottom: 5,
1342 /// left: 0,
1343 /// };
1344 ///
1345 /// assert!(edges.any(|value| *value == 0));
1346 /// assert!(edges.any(|value| *value > 0));
1347 /// assert!(!edges.any(|value| *value > 10));
1348 /// ```
1349 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1350 predicate(&self.top)
1351 || predicate(&self.right)
1352 || predicate(&self.bottom)
1353 || predicate(&self.left)
1354 }
1355}
1356
1357impl Edges<Length> {
1358 /// 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.
1359 ///
1360 /// 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.
1361 ///
1362 /// # Returns
1363 ///
1364 /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1365 ///
1366 /// # Examples
1367 ///
1368 /// ```
1369 /// # use zed::Edges;
1370 /// let auto_edges = Edges::auto();
1371 /// assert_eq!(auto_edges.top, Length::Auto);
1372 /// assert_eq!(auto_edges.right, Length::Auto);
1373 /// assert_eq!(auto_edges.bottom, Length::Auto);
1374 /// assert_eq!(auto_edges.left, Length::Auto);
1375 /// ```
1376 pub fn auto() -> Self {
1377 Self {
1378 top: Length::Auto,
1379 right: Length::Auto,
1380 bottom: Length::Auto,
1381 left: Length::Auto,
1382 }
1383 }
1384
1385 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1386 ///
1387 /// This is typically used when you want to specify that a box (like a padding or margin area)
1388 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1389 ///
1390 /// # Returns
1391 ///
1392 /// Returns an `Edges<Length>` with all edges set to zero length.
1393 ///
1394 /// # Examples
1395 ///
1396 /// ```
1397 /// # use zed::Edges;
1398 /// let no_edges = Edges::zero();
1399 /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels(0.))));
1400 /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels(0.))));
1401 /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels(0.))));
1402 /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels(0.))));
1403 /// ```
1404 pub fn zero() -> Self {
1405 Self {
1406 top: px(0.).into(),
1407 right: px(0.).into(),
1408 bottom: px(0.).into(),
1409 left: px(0.).into(),
1410 }
1411 }
1412}
1413
1414impl Edges<DefiniteLength> {
1415 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1416 ///
1417 /// This is typically used when you want to specify that a box (like a padding or margin area)
1418 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1419 ///
1420 /// # Returns
1421 ///
1422 /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1423 ///
1424 /// # Examples
1425 ///
1426 /// ```
1427 /// # use zed::Edges;
1428 /// let no_edges = Edges::zero();
1429 /// assert_eq!(no_edges.top, DefiniteLength::from(zed::px(0.)));
1430 /// assert_eq!(no_edges.right, DefiniteLength::from(zed::px(0.)));
1431 /// assert_eq!(no_edges.bottom, DefiniteLength::from(zed::px(0.)));
1432 /// assert_eq!(no_edges.left, DefiniteLength::from(zed::px(0.)));
1433 /// ```
1434 pub fn zero() -> Self {
1435 Self {
1436 top: px(0.).into(),
1437 right: px(0.).into(),
1438 bottom: px(0.).into(),
1439 left: px(0.).into(),
1440 }
1441 }
1442
1443 /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1444 ///
1445 /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1446 /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1447 ///
1448 /// # Arguments
1449 ///
1450 /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1451 /// * `rem_size` - `Pixels` representing the size of one REM unit.
1452 ///
1453 /// # Returns
1454 ///
1455 /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1456 ///
1457 /// # Examples
1458 ///
1459 /// ```
1460 /// # use zed::{Edges, DefiniteLength, px, AbsoluteLength, Size};
1461 /// let edges = Edges {
1462 /// top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1463 /// right: DefiniteLength::Fraction(0.5),
1464 /// bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1465 /// left: DefiniteLength::Fraction(0.25),
1466 /// };
1467 /// let parent_size = Size {
1468 /// width: AbsoluteLength::Pixels(px(200.0)),
1469 /// height: AbsoluteLength::Pixels(px(100.0)),
1470 /// };
1471 /// let rem_size = px(16.0);
1472 /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1473 ///
1474 /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1475 /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1476 /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1477 /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1478 /// ```
1479 pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1480 Edges {
1481 top: self.top.to_pixels(parent_size.height, rem_size),
1482 right: self.right.to_pixels(parent_size.width, rem_size),
1483 bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1484 left: self.left.to_pixels(parent_size.width, rem_size),
1485 }
1486 }
1487}
1488
1489impl Edges<AbsoluteLength> {
1490 /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1491 ///
1492 /// This is typically used when you want to specify that a box (like a padding or margin area)
1493 /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1494 ///
1495 /// # Returns
1496 ///
1497 /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
1498 ///
1499 /// # Examples
1500 ///
1501 /// ```
1502 /// # use zed::Edges;
1503 /// let no_edges = Edges::zero();
1504 /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels(0.0)));
1505 /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels(0.0)));
1506 /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels(0.0)));
1507 /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels(0.0)));
1508 /// ```
1509 pub fn zero() -> Self {
1510 Self {
1511 top: px(0.).into(),
1512 right: px(0.).into(),
1513 bottom: px(0.).into(),
1514 left: px(0.).into(),
1515 }
1516 }
1517
1518 /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
1519 ///
1520 /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
1521 /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
1522 ///
1523 /// # Arguments
1524 ///
1525 /// * `rem_size` - The size of one rem unit in pixels.
1526 ///
1527 /// # Returns
1528 ///
1529 /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1530 ///
1531 /// # Examples
1532 ///
1533 /// ```
1534 /// # use zed::{Edges, AbsoluteLength, Pixels, px};
1535 /// let edges = Edges {
1536 /// top: AbsoluteLength::Pixels(px(10.0)),
1537 /// right: AbsoluteLength::Rems(rems(1.0)),
1538 /// bottom: AbsoluteLength::Pixels(px(20.0)),
1539 /// left: AbsoluteLength::Rems(rems(2.0)),
1540 /// };
1541 /// let rem_size = px(16.0);
1542 /// let edges_in_pixels = edges.to_pixels(rem_size);
1543 ///
1544 /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
1545 /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
1546 /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
1547 /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
1548 /// ```
1549 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
1550 Edges {
1551 top: self.top.to_pixels(rem_size),
1552 right: self.right.to_pixels(rem_size),
1553 bottom: self.bottom.to_pixels(rem_size),
1554 left: self.left.to_pixels(rem_size),
1555 }
1556 }
1557}
1558
1559impl Edges<Pixels> {
1560 /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
1561 ///
1562 /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
1563 ///
1564 /// # Arguments
1565 ///
1566 /// * `factor` - The scaling factor to apply to each edge.
1567 ///
1568 /// # Returns
1569 ///
1570 /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
1571 ///
1572 /// # Examples
1573 ///
1574 /// ```
1575 /// # use zed::{Edges, Pixels};
1576 /// let edges = Edges {
1577 /// top: Pixels(10.0),
1578 /// right: Pixels(20.0),
1579 /// bottom: Pixels(30.0),
1580 /// left: Pixels(40.0),
1581 /// };
1582 /// let scaled_edges = edges.scale(2.0);
1583 /// assert_eq!(scaled_edges.top, ScaledPixels(20.0));
1584 /// assert_eq!(scaled_edges.right, ScaledPixels(40.0));
1585 /// assert_eq!(scaled_edges.bottom, ScaledPixels(60.0));
1586 /// assert_eq!(scaled_edges.left, ScaledPixels(80.0));
1587 /// ```
1588 pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
1589 Edges {
1590 top: self.top.scale(factor),
1591 right: self.right.scale(factor),
1592 bottom: self.bottom.scale(factor),
1593 left: self.left.scale(factor),
1594 }
1595 }
1596
1597 /// Returns the maximum value of any edge.
1598 ///
1599 /// # Returns
1600 ///
1601 /// The maximum `Pixels` value among all four edges.
1602 pub fn max(&self) -> Pixels {
1603 self.top.max(self.right).max(self.bottom).max(self.left)
1604 }
1605}
1606
1607impl From<f32> for Edges<Pixels> {
1608 fn from(val: f32) -> Self {
1609 Edges {
1610 top: val.into(),
1611 right: val.into(),
1612 bottom: val.into(),
1613 left: val.into(),
1614 }
1615 }
1616}
1617
1618/// Represents the corners of a box in a 2D space, such as border radius.
1619///
1620/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
1621#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1622#[refineable(Debug)]
1623#[repr(C)]
1624pub struct Corners<T: Clone + Default + Debug> {
1625 /// The value associated with the top left corner.
1626 pub top_left: T,
1627 /// The value associated with the top right corner.
1628 pub top_right: T,
1629 /// The value associated with the bottom right corner.
1630 pub bottom_right: T,
1631 /// The value associated with the bottom left corner.
1632 pub bottom_left: T,
1633}
1634
1635impl<T> Corners<T>
1636where
1637 T: Clone + Default + Debug,
1638{
1639 /// Constructs `Corners` where all sides are set to the same specified value.
1640 ///
1641 /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1642 /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1643 /// such as a uniform border radius on a rectangle.
1644 ///
1645 /// # Arguments
1646 ///
1647 /// * `value` - The value to set for all four corners.
1648 ///
1649 /// # Returns
1650 ///
1651 /// An `Corners` instance with all corners set to the given value.
1652 ///
1653 /// # Examples
1654 ///
1655 /// ```
1656 /// # use zed::Corners;
1657 /// let uniform_corners = Corners::all(5.0);
1658 /// assert_eq!(uniform_corners.top_left, 5.0);
1659 /// assert_eq!(uniform_corners.top_right, 5.0);
1660 /// assert_eq!(uniform_corners.bottom_right, 5.0);
1661 /// assert_eq!(uniform_corners.bottom_left, 5.0);
1662 /// ```
1663 pub fn all(value: T) -> Self {
1664 Self {
1665 top_left: value.clone(),
1666 top_right: value.clone(),
1667 bottom_right: value.clone(),
1668 bottom_left: value,
1669 }
1670 }
1671}
1672
1673impl Corners<AbsoluteLength> {
1674 /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1675 /// `Pixels` do not exceed half of the maximum of the provided size's width and height.
1676 ///
1677 /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1678 /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1679 ///
1680 /// # Arguments
1681 ///
1682 /// * `size` - The `Size<Pixels>` against which the maximum allowable radius is determined.
1683 /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1684 ///
1685 /// # Returns
1686 ///
1687 /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1688 /// maximum allowable radius based on the provided size.
1689 ///
1690 /// # Examples
1691 ///
1692 /// ```
1693 /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1694 /// let corners = Corners {
1695 /// top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1696 /// top_right: AbsoluteLength::Rems(Rems(1.0)),
1697 /// bottom_right: AbsoluteLength::Pixels(Pixels(20.0)),
1698 /// bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1699 /// };
1700 /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1701 /// let rem_size = Pixels(16.0);
1702 /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1703 ///
1704 /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1705 /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1706 /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1707 /// assert_eq!(corners_in_pixels.bottom_right, Pixels(20.0).min(Pixels(25.0))); // Clamped to 25.0
1708 /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped
1709 /// ```
1710 pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1711 let max = size.width.max(size.height) / 2.;
1712 Corners {
1713 top_left: self.top_left.to_pixels(rem_size).min(max),
1714 top_right: self.top_right.to_pixels(rem_size).min(max),
1715 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1716 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1717 }
1718 }
1719}
1720
1721impl Corners<Pixels> {
1722 /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1723 ///
1724 /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1725 ///
1726 /// # Arguments
1727 ///
1728 /// * `factor` - The scaling factor to apply to each corner.
1729 ///
1730 /// # Returns
1731 ///
1732 /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1733 ///
1734 /// # Examples
1735 ///
1736 /// ```
1737 /// # use zed::{Corners, Pixels};
1738 /// let corners = Corners {
1739 /// top_left: Pixels(10.0),
1740 /// top_right: Pixels(20.0),
1741 /// bottom_right: Pixels(30.0),
1742 /// bottom_left: Pixels(40.0),
1743 /// };
1744 /// let scaled_corners = corners.scale(2.0);
1745 /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1746 /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1747 /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1748 /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1749 /// ```
1750 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1751 Corners {
1752 top_left: self.top_left.scale(factor),
1753 top_right: self.top_right.scale(factor),
1754 bottom_right: self.bottom_right.scale(factor),
1755 bottom_left: self.bottom_left.scale(factor),
1756 }
1757 }
1758
1759 /// Returns the maximum value of any corner.
1760 ///
1761 /// # Returns
1762 ///
1763 /// The maximum `Pixels` value among all four corners.
1764 pub fn max(&self) -> Pixels {
1765 self.top_left
1766 .max(self.top_right)
1767 .max(self.bottom_right)
1768 .max(self.bottom_left)
1769 }
1770}
1771
1772impl<T: Clone + Default + Debug> Corners<T> {
1773 /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
1774 ///
1775 /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
1776 /// that defines how to convert between the two types. The closure is applied to each field
1777 /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
1778 ///
1779 /// # Arguments
1780 ///
1781 /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1782 ///
1783 /// # Returns
1784 ///
1785 /// Returns a new `Corners<U>` with each field mapped by the provided function.
1786 ///
1787 /// # Examples
1788 ///
1789 /// ```
1790 /// # use zed::{Corners, Pixels};
1791 /// let corners = Corners {
1792 /// top_left: Pixels(10.0),
1793 /// top_right: Pixels(20.0),
1794 /// bottom_right: Pixels(30.0),
1795 /// bottom_left: Pixels(40.0),
1796 /// };
1797 /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
1798 /// assert_eq!(corners_in_rems, Corners {
1799 /// top_left: Rems(0.625),
1800 /// top_right: Rems(1.25),
1801 /// bottom_right: Rems(1.875),
1802 /// bottom_left: Rems(2.5),
1803 /// });
1804 /// ```
1805 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
1806 where
1807 U: Clone + Default + Debug,
1808 {
1809 Corners {
1810 top_left: f(&self.top_left),
1811 top_right: f(&self.top_right),
1812 bottom_right: f(&self.bottom_right),
1813 bottom_left: f(&self.bottom_left),
1814 }
1815 }
1816}
1817
1818impl<T> Mul for Corners<T>
1819where
1820 T: Mul<Output = T> + Clone + Default + Debug,
1821{
1822 type Output = Self;
1823
1824 fn mul(self, rhs: Self) -> Self::Output {
1825 Self {
1826 top_left: self.top_left.clone() * rhs.top_left,
1827 top_right: self.top_right.clone() * rhs.top_right,
1828 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
1829 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
1830 }
1831 }
1832}
1833
1834impl<T, S> MulAssign<S> for Corners<T>
1835where
1836 T: Mul<S, Output = T> + Clone + Default + Debug,
1837 S: Clone,
1838{
1839 fn mul_assign(&mut self, rhs: S) {
1840 self.top_left = self.top_left.clone() * rhs.clone();
1841 self.top_right = self.top_right.clone() * rhs.clone();
1842 self.bottom_right = self.bottom_right.clone() * rhs.clone();
1843 self.bottom_left = self.bottom_left.clone() * rhs;
1844 }
1845}
1846
1847impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
1848
1849impl From<f32> for Corners<Pixels> {
1850 fn from(val: f32) -> Self {
1851 Corners {
1852 top_left: val.into(),
1853 top_right: val.into(),
1854 bottom_right: val.into(),
1855 bottom_left: val.into(),
1856 }
1857 }
1858}
1859
1860impl From<Pixels> for Corners<Pixels> {
1861 fn from(val: Pixels) -> Self {
1862 Corners {
1863 top_left: val,
1864 top_right: val,
1865 bottom_right: val,
1866 bottom_left: val,
1867 }
1868 }
1869}
1870
1871/// Represents a length in pixels, the base unit of measurement in the UI framework.
1872///
1873/// `Pixels` is a value type that represents an absolute length in pixels, which is used
1874/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
1875/// of measurement for all visual elements and layout calculations.
1876///
1877/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
1878/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
1879/// is typically rounded to the nearest integer.
1880///
1881/// # Examples
1882///
1883/// ```
1884/// use zed::Pixels;
1885///
1886/// // Define a length of 10 pixels
1887/// let length = Pixels(10.0);
1888///
1889/// // Define a length and scale it by a factor of 2
1890/// let scaled_length = length.scale(2.0);
1891/// assert_eq!(scaled_length, Pixels(20.0));
1892/// ```
1893#[derive(
1894 Clone,
1895 Copy,
1896 Default,
1897 Add,
1898 AddAssign,
1899 Sub,
1900 SubAssign,
1901 Neg,
1902 Div,
1903 DivAssign,
1904 PartialEq,
1905 Serialize,
1906 Deserialize,
1907)]
1908#[repr(transparent)]
1909pub struct Pixels(pub f32);
1910
1911impl std::ops::Div for Pixels {
1912 type Output = f32;
1913
1914 fn div(self, rhs: Self) -> Self::Output {
1915 self.0 / rhs.0
1916 }
1917}
1918
1919impl std::ops::DivAssign for Pixels {
1920 fn div_assign(&mut self, rhs: Self) {
1921 *self = Self(self.0 / rhs.0);
1922 }
1923}
1924
1925impl std::ops::RemAssign for Pixels {
1926 fn rem_assign(&mut self, rhs: Self) {
1927 self.0 %= rhs.0;
1928 }
1929}
1930
1931impl std::ops::Rem for Pixels {
1932 type Output = Self;
1933
1934 fn rem(self, rhs: Self) -> Self {
1935 Self(self.0 % rhs.0)
1936 }
1937}
1938
1939impl Mul<f32> for Pixels {
1940 type Output = Pixels;
1941
1942 fn mul(self, other: f32) -> Pixels {
1943 Pixels(self.0 * other)
1944 }
1945}
1946
1947impl Mul<usize> for Pixels {
1948 type Output = Pixels;
1949
1950 fn mul(self, other: usize) -> Pixels {
1951 Pixels(self.0 * other as f32)
1952 }
1953}
1954
1955impl Mul<Pixels> for f32 {
1956 type Output = Pixels;
1957
1958 fn mul(self, rhs: Pixels) -> Self::Output {
1959 Pixels(self * rhs.0)
1960 }
1961}
1962
1963impl MulAssign<f32> for Pixels {
1964 fn mul_assign(&mut self, other: f32) {
1965 self.0 *= other;
1966 }
1967}
1968
1969impl Pixels {
1970 /// Represents zero pixels.
1971 pub const ZERO: Pixels = Pixels(0.0);
1972 /// The maximum value that can be represented by `Pixels`.
1973 pub const MAX: Pixels = Pixels(f32::MAX);
1974
1975 /// Floors the `Pixels` value to the nearest whole number.
1976 ///
1977 /// # Returns
1978 ///
1979 /// Returns a new `Pixels` instance with the floored value.
1980 pub fn floor(&self) -> Self {
1981 Self(self.0.floor())
1982 }
1983
1984 /// Rounds the `Pixels` value to the nearest whole number.
1985 ///
1986 /// # Returns
1987 ///
1988 /// Returns a new `Pixels` instance with the rounded value.
1989 pub fn round(&self) -> Self {
1990 Self(self.0.round())
1991 }
1992
1993 /// Returns the ceiling of the `Pixels` value to the nearest whole number.
1994 ///
1995 /// # Returns
1996 ///
1997 /// Returns a new `Pixels` instance with the ceiling value.
1998 pub fn ceil(&self) -> Self {
1999 Self(self.0.ceil())
2000 }
2001
2002 /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2003 ///
2004 /// This method is used when adjusting pixel values for display scaling factors,
2005 /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2006 /// thus requires scaling to maintain visual consistency and readability.
2007 ///
2008 /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2009 /// calculations where display scaling is considered.
2010 pub fn scale(&self, factor: f32) -> ScaledPixels {
2011 ScaledPixels(self.0 * factor)
2012 }
2013
2014 /// Raises the `Pixels` value to a given power.
2015 ///
2016 /// # Arguments
2017 ///
2018 /// * `exponent` - The exponent to raise the `Pixels` value by.
2019 ///
2020 /// # Returns
2021 ///
2022 /// Returns a new `Pixels` instance with the value raised to the given exponent.
2023 pub fn pow(&self, exponent: f32) -> Self {
2024 Self(self.0.powf(exponent))
2025 }
2026
2027 /// Returns the absolute value of the `Pixels`.
2028 ///
2029 /// # Returns
2030 ///
2031 /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2032 pub fn abs(&self) -> Self {
2033 Self(self.0.abs())
2034 }
2035}
2036
2037impl Mul<Pixels> for Pixels {
2038 type Output = Pixels;
2039
2040 fn mul(self, rhs: Pixels) -> Self::Output {
2041 Pixels(self.0 * rhs.0)
2042 }
2043}
2044
2045impl Eq for Pixels {}
2046
2047impl PartialOrd for Pixels {
2048 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2049 Some(self.cmp(other))
2050 }
2051}
2052
2053impl Ord for Pixels {
2054 fn cmp(&self, other: &Self) -> cmp::Ordering {
2055 self.0.total_cmp(&other.0)
2056 }
2057}
2058
2059impl std::hash::Hash for Pixels {
2060 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2061 self.0.to_bits().hash(state);
2062 }
2063}
2064
2065impl From<f64> for Pixels {
2066 fn from(pixels: f64) -> Self {
2067 Pixels(pixels as f32)
2068 }
2069}
2070
2071impl From<f32> for Pixels {
2072 fn from(pixels: f32) -> Self {
2073 Pixels(pixels)
2074 }
2075}
2076
2077impl Debug for Pixels {
2078 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2079 write!(f, "{} px", self.0)
2080 }
2081}
2082
2083impl From<Pixels> for f32 {
2084 fn from(pixels: Pixels) -> Self {
2085 pixels.0
2086 }
2087}
2088
2089impl From<&Pixels> for f32 {
2090 fn from(pixels: &Pixels) -> Self {
2091 pixels.0
2092 }
2093}
2094
2095impl From<Pixels> for f64 {
2096 fn from(pixels: Pixels) -> Self {
2097 pixels.0 as f64
2098 }
2099}
2100
2101impl From<Pixels> for u32 {
2102 fn from(pixels: Pixels) -> Self {
2103 pixels.0 as u32
2104 }
2105}
2106
2107impl From<u32> for Pixels {
2108 fn from(pixels: u32) -> Self {
2109 Pixels(pixels as f32)
2110 }
2111}
2112
2113impl From<Pixels> for usize {
2114 fn from(pixels: Pixels) -> Self {
2115 pixels.0 as usize
2116 }
2117}
2118
2119impl From<usize> for Pixels {
2120 fn from(pixels: usize) -> Self {
2121 Pixels(pixels as f32)
2122 }
2123}
2124
2125/// Represents physical pixels on the display.
2126///
2127/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2128/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2129/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2130/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2131/// display.
2132#[derive(
2133 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
2134)]
2135#[repr(transparent)]
2136pub struct DevicePixels(pub(crate) i32);
2137
2138impl DevicePixels {
2139 /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2140 ///
2141 /// This function is useful when working with graphical data that needs to be stored in a buffer,
2142 /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2143 ///
2144 /// # Arguments
2145 ///
2146 /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2147 ///
2148 /// # Returns
2149 ///
2150 /// The number of bytes required to represent the `DevicePixels` value in memory.
2151 ///
2152 /// # Examples
2153 ///
2154 /// ```
2155 /// # use zed::DevicePixels;
2156 /// let pixels = DevicePixels(10); // 10 device pixels
2157 /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2158 /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2159 /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2160 /// ```
2161 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2162 self.0 as u32 * bytes_per_pixel as u32
2163 }
2164}
2165
2166impl fmt::Debug for DevicePixels {
2167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2168 write!(f, "{} px (device)", self.0)
2169 }
2170}
2171
2172impl From<DevicePixels> for i32 {
2173 fn from(device_pixels: DevicePixels) -> Self {
2174 device_pixels.0
2175 }
2176}
2177
2178impl From<i32> for DevicePixels {
2179 fn from(device_pixels: i32) -> Self {
2180 DevicePixels(device_pixels)
2181 }
2182}
2183
2184impl From<u32> for DevicePixels {
2185 fn from(device_pixels: u32) -> Self {
2186 DevicePixels(device_pixels as i32)
2187 }
2188}
2189
2190impl From<DevicePixels> for u32 {
2191 fn from(device_pixels: DevicePixels) -> Self {
2192 device_pixels.0 as u32
2193 }
2194}
2195
2196impl From<DevicePixels> for u64 {
2197 fn from(device_pixels: DevicePixels) -> Self {
2198 device_pixels.0 as u64
2199 }
2200}
2201
2202impl From<u64> for DevicePixels {
2203 fn from(device_pixels: u64) -> Self {
2204 DevicePixels(device_pixels as i32)
2205 }
2206}
2207
2208impl From<DevicePixels> for usize {
2209 fn from(device_pixels: DevicePixels) -> Self {
2210 device_pixels.0 as usize
2211 }
2212}
2213
2214impl From<usize> for DevicePixels {
2215 fn from(device_pixels: usize) -> Self {
2216 DevicePixels(device_pixels as i32)
2217 }
2218}
2219
2220/// Represents scaled pixels that take into account the device's scale factor.
2221///
2222/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2223/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2224/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2225/// dimensions and positions can be specified in a way that scales appropriately across different
2226/// display resolutions.
2227#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2228#[repr(transparent)]
2229pub struct ScaledPixels(pub(crate) f32);
2230
2231impl ScaledPixels {
2232 /// Floors the `ScaledPixels` value to the nearest whole number.
2233 ///
2234 /// # Returns
2235 ///
2236 /// Returns a new `ScaledPixels` instance with the floored value.
2237 pub fn floor(&self) -> Self {
2238 Self(self.0.floor())
2239 }
2240
2241 /// Rounds the `ScaledPixels` value to the nearest whole number.
2242 ///
2243 /// # Returns
2244 ///
2245 /// Returns a new `ScaledPixels` instance with the rounded value.
2246 pub fn ceil(&self) -> Self {
2247 Self(self.0.ceil())
2248 }
2249}
2250
2251impl Eq for ScaledPixels {}
2252
2253impl Debug for ScaledPixels {
2254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2255 write!(f, "{} px (scaled)", self.0)
2256 }
2257}
2258
2259impl From<ScaledPixels> for DevicePixels {
2260 fn from(scaled: ScaledPixels) -> Self {
2261 DevicePixels(scaled.0.ceil() as i32)
2262 }
2263}
2264
2265impl From<DevicePixels> for ScaledPixels {
2266 fn from(device: DevicePixels) -> Self {
2267 ScaledPixels(device.0 as f32)
2268 }
2269}
2270
2271impl From<ScaledPixels> for f64 {
2272 fn from(scaled_pixels: ScaledPixels) -> Self {
2273 scaled_pixels.0 as f64
2274 }
2275}
2276
2277/// Represents pixels in a global coordinate space, which can span across multiple displays.
2278///
2279/// `GlobalPixels` is used when dealing with a coordinate system that is not limited to a single
2280/// display's boundaries. This type is particularly useful in multi-monitor setups where
2281/// positioning and measurements need to be consistent and relative to a "global" origin point
2282/// rather than being relative to any individual display.
2283#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2284#[repr(transparent)]
2285pub struct GlobalPixels(pub(crate) f32);
2286
2287impl Debug for GlobalPixels {
2288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2289 write!(f, "{} px (global coordinate space)", self.0)
2290 }
2291}
2292
2293impl From<GlobalPixels> for f64 {
2294 fn from(global_pixels: GlobalPixels) -> Self {
2295 global_pixels.0 as f64
2296 }
2297}
2298
2299impl From<f64> for GlobalPixels {
2300 fn from(global_pixels: f64) -> Self {
2301 GlobalPixels(global_pixels as f32)
2302 }
2303}
2304
2305/// 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].
2306///
2307/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2308/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2309/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2310/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2311///
2312/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2313///
2314/// [set_rem_size]: crate::WindowContext::set_rem_size
2315#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2316pub struct Rems(pub f32);
2317
2318impl Mul<Pixels> for Rems {
2319 type Output = Pixels;
2320
2321 fn mul(self, other: Pixels) -> Pixels {
2322 Pixels(self.0 * other.0)
2323 }
2324}
2325
2326impl Debug for Rems {
2327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2328 write!(f, "{} rem", self.0)
2329 }
2330}
2331
2332/// Represents an absolute length in pixels or rems.
2333///
2334/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2335/// affected by the current font size, or a number of rems, which is relative to the font size of
2336/// the root element. It is used for specifying dimensions that are either independent of or
2337/// related to the typographic scale.
2338#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2339pub enum AbsoluteLength {
2340 /// A length in pixels.
2341 Pixels(Pixels),
2342 /// A length in rems.
2343 Rems(Rems),
2344}
2345
2346impl AbsoluteLength {
2347 /// Checks if the absolute length is zero.
2348 pub fn is_zero(&self) -> bool {
2349 match self {
2350 AbsoluteLength::Pixels(px) => px.0 == 0.0,
2351 AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2352 }
2353 }
2354}
2355
2356impl From<Pixels> for AbsoluteLength {
2357 fn from(pixels: Pixels) -> Self {
2358 AbsoluteLength::Pixels(pixels)
2359 }
2360}
2361
2362impl From<Rems> for AbsoluteLength {
2363 fn from(rems: Rems) -> Self {
2364 AbsoluteLength::Rems(rems)
2365 }
2366}
2367
2368impl AbsoluteLength {
2369 /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2370 ///
2371 /// # Arguments
2372 ///
2373 /// * `rem_size` - The size of one rem in pixels.
2374 ///
2375 /// # Returns
2376 ///
2377 /// Returns the `AbsoluteLength` as `Pixels`.
2378 ///
2379 /// # Examples
2380 ///
2381 /// ```
2382 /// # use zed::{AbsoluteLength, Pixels};
2383 /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2384 /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2385 /// let rem_size = Pixels(16.0);
2386 ///
2387 /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2388 /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2389 /// ```
2390 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2391 match self {
2392 AbsoluteLength::Pixels(pixels) => *pixels,
2393 AbsoluteLength::Rems(rems) => *rems * rem_size,
2394 }
2395 }
2396}
2397
2398impl Default for AbsoluteLength {
2399 fn default() -> Self {
2400 px(0.).into()
2401 }
2402}
2403
2404/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2405///
2406/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2407/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2408/// fraction of the parent's size.
2409#[derive(Clone, Copy, Neg, PartialEq)]
2410pub enum DefiniteLength {
2411 /// An absolute length specified in pixels or rems.
2412 Absolute(AbsoluteLength),
2413 /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2414 Fraction(f32),
2415}
2416
2417impl DefiniteLength {
2418 /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2419 ///
2420 /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2421 /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2422 ///
2423 /// # Arguments
2424 ///
2425 /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2426 /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2427 ///
2428 /// # Returns
2429 ///
2430 /// Returns the `DefiniteLength` as `Pixels`.
2431 ///
2432 /// # Examples
2433 ///
2434 /// ```
2435 /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2436 /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2437 /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2438 /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2439 /// let base_size = AbsoluteLength::Pixels(px(100.0));
2440 /// let rem_size = px(16.0);
2441 ///
2442 /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2443 /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2444 /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2445 /// ```
2446 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2447 match self {
2448 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2449 DefiniteLength::Fraction(fraction) => match base_size {
2450 AbsoluteLength::Pixels(px) => px * *fraction,
2451 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2452 },
2453 }
2454 }
2455}
2456
2457impl Debug for DefiniteLength {
2458 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2459 match self {
2460 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2461 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2462 }
2463 }
2464}
2465
2466impl From<Pixels> for DefiniteLength {
2467 fn from(pixels: Pixels) -> Self {
2468 Self::Absolute(pixels.into())
2469 }
2470}
2471
2472impl From<Rems> for DefiniteLength {
2473 fn from(rems: Rems) -> Self {
2474 Self::Absolute(rems.into())
2475 }
2476}
2477
2478impl From<AbsoluteLength> for DefiniteLength {
2479 fn from(length: AbsoluteLength) -> Self {
2480 Self::Absolute(length)
2481 }
2482}
2483
2484impl Default for DefiniteLength {
2485 fn default() -> Self {
2486 Self::Absolute(AbsoluteLength::default())
2487 }
2488}
2489
2490/// A length that can be defined in pixels, rems, percent of parent, or auto.
2491#[derive(Clone, Copy)]
2492pub enum Length {
2493 /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2494 Definite(DefiniteLength),
2495 /// An automatic length that is determined by the context in which it is used.
2496 Auto,
2497}
2498
2499impl Debug for Length {
2500 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2501 match self {
2502 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2503 Length::Auto => write!(f, "auto"),
2504 }
2505 }
2506}
2507
2508/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2509///
2510/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2511/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2512///
2513/// # Arguments
2514///
2515/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2516///
2517/// # Returns
2518///
2519/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2520pub fn relative(fraction: f32) -> DefiniteLength {
2521 DefiniteLength::Fraction(fraction)
2522}
2523
2524/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2525pub fn phi() -> DefiniteLength {
2526 relative(1.618_034)
2527}
2528
2529/// Constructs a `Rems` value representing a length in rems.
2530///
2531/// # Arguments
2532///
2533/// * `rems` - The number of rems for the length.
2534///
2535/// # Returns
2536///
2537/// A `Rems` representing the specified number of rems.
2538pub fn rems(rems: f32) -> Rems {
2539 Rems(rems)
2540}
2541
2542/// Constructs a `Pixels` value representing a length in pixels.
2543///
2544/// # Arguments
2545///
2546/// * `pixels` - The number of pixels for the length.
2547///
2548/// # Returns
2549///
2550/// A `Pixels` representing the specified number of pixels.
2551pub const fn px(pixels: f32) -> Pixels {
2552 Pixels(pixels)
2553}
2554
2555/// Returns a `Length` representing an automatic length.
2556///
2557/// The `auto` length is often used in layout calculations where the length should be determined
2558/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2559/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2560/// to instruct the layout engine to calculate the size based on other factors like the size of the
2561/// container or the intrinsic size of the content.
2562///
2563/// # Returns
2564///
2565/// A `Length` variant set to `Auto`.
2566pub fn auto() -> Length {
2567 Length::Auto
2568}
2569
2570impl From<Pixels> for Length {
2571 fn from(pixels: Pixels) -> Self {
2572 Self::Definite(pixels.into())
2573 }
2574}
2575
2576impl From<Rems> for Length {
2577 fn from(rems: Rems) -> Self {
2578 Self::Definite(rems.into())
2579 }
2580}
2581
2582impl From<DefiniteLength> for Length {
2583 fn from(length: DefiniteLength) -> Self {
2584 Self::Definite(length)
2585 }
2586}
2587
2588impl From<AbsoluteLength> for Length {
2589 fn from(length: AbsoluteLength) -> Self {
2590 Self::Definite(length.into())
2591 }
2592}
2593
2594impl Default for Length {
2595 fn default() -> Self {
2596 Self::Definite(DefiniteLength::default())
2597 }
2598}
2599
2600impl From<()> for Length {
2601 fn from(_: ()) -> Self {
2602 Self::Definite(DefiniteLength::default())
2603 }
2604}
2605
2606/// Provides a trait for types that can calculate half of their value.
2607///
2608/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2609/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2610/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2611pub trait Half {
2612 /// Returns half of the current value.
2613 ///
2614 /// # Returns
2615 ///
2616 /// A new instance of the implementing type, representing half of the original value.
2617 fn half(&self) -> Self;
2618}
2619
2620impl Half for f32 {
2621 fn half(&self) -> Self {
2622 self / 2.
2623 }
2624}
2625
2626impl Half for DevicePixels {
2627 fn half(&self) -> Self {
2628 Self(self.0 / 2)
2629 }
2630}
2631
2632impl Half for ScaledPixels {
2633 fn half(&self) -> Self {
2634 Self(self.0 / 2.)
2635 }
2636}
2637
2638impl Half for Pixels {
2639 fn half(&self) -> Self {
2640 Self(self.0 / 2.)
2641 }
2642}
2643
2644impl Half for Rems {
2645 fn half(&self) -> Self {
2646 Self(self.0 / 2.)
2647 }
2648}
2649
2650impl Half for GlobalPixels {
2651 fn half(&self) -> Self {
2652 Self(self.0 / 2.)
2653 }
2654}
2655
2656/// A trait for checking if a value is zero.
2657///
2658/// This trait provides a method to determine if a value is considered to be zero.
2659/// It is implemented for various numeric and length-related types where the concept
2660/// of zero is applicable. This can be useful for comparisons, optimizations, or
2661/// determining if an operation has a neutral effect.
2662pub trait IsZero {
2663 /// Determines if the value is zero.
2664 ///
2665 /// # Returns
2666 ///
2667 /// Returns `true` if the value is zero, `false` otherwise.
2668 fn is_zero(&self) -> bool;
2669}
2670
2671impl IsZero for DevicePixels {
2672 fn is_zero(&self) -> bool {
2673 self.0 == 0
2674 }
2675}
2676
2677impl IsZero for ScaledPixels {
2678 fn is_zero(&self) -> bool {
2679 self.0 == 0.
2680 }
2681}
2682
2683impl IsZero for Pixels {
2684 fn is_zero(&self) -> bool {
2685 self.0 == 0.
2686 }
2687}
2688
2689impl IsZero for Rems {
2690 fn is_zero(&self) -> bool {
2691 self.0 == 0.
2692 }
2693}
2694
2695impl IsZero for AbsoluteLength {
2696 fn is_zero(&self) -> bool {
2697 match self {
2698 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
2699 AbsoluteLength::Rems(rems) => rems.is_zero(),
2700 }
2701 }
2702}
2703
2704impl IsZero for DefiniteLength {
2705 fn is_zero(&self) -> bool {
2706 match self {
2707 DefiniteLength::Absolute(length) => length.is_zero(),
2708 DefiniteLength::Fraction(fraction) => *fraction == 0.,
2709 }
2710 }
2711}
2712
2713impl IsZero for Length {
2714 fn is_zero(&self) -> bool {
2715 match self {
2716 Length::Definite(length) => length.is_zero(),
2717 Length::Auto => false,
2718 }
2719 }
2720}
2721
2722impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
2723 fn is_zero(&self) -> bool {
2724 self.x.is_zero() && self.y.is_zero()
2725 }
2726}
2727
2728impl<T> IsZero for Size<T>
2729where
2730 T: IsZero + Default + Debug + Clone,
2731{
2732 fn is_zero(&self) -> bool {
2733 self.width.is_zero() || self.height.is_zero()
2734 }
2735}
2736
2737impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
2738 fn is_zero(&self) -> bool {
2739 self.size.is_zero()
2740 }
2741}
2742
2743impl<T> IsZero for Corners<T>
2744where
2745 T: IsZero + Clone + Default + Debug,
2746{
2747 fn is_zero(&self) -> bool {
2748 self.top_left.is_zero()
2749 && self.top_right.is_zero()
2750 && self.bottom_right.is_zero()
2751 && self.bottom_left.is_zero()
2752 }
2753}
2754
2755#[cfg(test)]
2756mod tests {
2757 use super::*;
2758
2759 #[test]
2760 fn test_bounds_intersects() {
2761 let bounds1 = Bounds {
2762 origin: Point { x: 0.0, y: 0.0 },
2763 size: Size {
2764 width: 5.0,
2765 height: 5.0,
2766 },
2767 };
2768 let bounds2 = Bounds {
2769 origin: Point { x: 4.0, y: 4.0 },
2770 size: Size {
2771 width: 5.0,
2772 height: 5.0,
2773 },
2774 };
2775 let bounds3 = Bounds {
2776 origin: Point { x: 10.0, y: 10.0 },
2777 size: Size {
2778 width: 5.0,
2779 height: 5.0,
2780 },
2781 };
2782
2783 // Test Case 1: Intersecting bounds
2784 assert_eq!(bounds1.intersects(&bounds2), true);
2785
2786 // Test Case 2: Non-Intersecting bounds
2787 assert_eq!(bounds1.intersects(&bounds3), false);
2788
2789 // Test Case 3: Bounds intersecting with themselves
2790 assert_eq!(bounds1.intersects(&bounds1), true);
2791 }
2792}