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