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