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#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1586#[refineable(Debug)]
1587#[repr(C)]
1588pub struct Corners<T: Clone + Default + Debug> {
1589 pub top_left: T,
1590 pub top_right: T,
1591 pub bottom_right: T,
1592 pub bottom_left: T,
1593}
1594
1595impl<T> Corners<T>
1596where
1597 T: Clone + Default + Debug,
1598{
1599 /// Constructs `Corners` where all sides are set to the same specified value.
1600 ///
1601 /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1602 /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1603 /// such as a uniform border radius on a rectangle.
1604 ///
1605 /// # Arguments
1606 ///
1607 /// * `value` - The value to set for all four corners.
1608 ///
1609 /// # Returns
1610 ///
1611 /// An `Corners` instance with all corners set to the given value.
1612 ///
1613 /// # Examples
1614 ///
1615 /// ```
1616 /// # use zed::Corners;
1617 /// let uniform_corners = Corners::all(5.0);
1618 /// assert_eq!(uniform_corners.top_left, 5.0);
1619 /// assert_eq!(uniform_corners.top_right, 5.0);
1620 /// assert_eq!(uniform_corners.bottom_right, 5.0);
1621 /// assert_eq!(uniform_corners.bottom_left, 5.0);
1622 /// ```
1623 pub fn all(value: T) -> Self {
1624 Self {
1625 top_left: value.clone(),
1626 top_right: value.clone(),
1627 bottom_right: value.clone(),
1628 bottom_left: value,
1629 }
1630 }
1631}
1632
1633impl Corners<AbsoluteLength> {
1634 /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1635 /// `Pixels` do not exceed half of the maximum of the provided size's width and height.
1636 ///
1637 /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1638 /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1639 ///
1640 /// # Arguments
1641 ///
1642 /// * `size` - The `Size<Pixels>` against which the maximum allowable radius is determined.
1643 /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1644 ///
1645 /// # Returns
1646 ///
1647 /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1648 /// maximum allowable radius based on the provided size.
1649 ///
1650 /// # Examples
1651 ///
1652 /// ```
1653 /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1654 /// let corners = Corners {
1655 /// top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1656 /// top_right: AbsoluteLength::Rems(Rems(1.0)),
1657 /// bottom_right: AbsoluteLength::Pixels(Pixels(20.0)),
1658 /// bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1659 /// };
1660 /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1661 /// let rem_size = Pixels(16.0);
1662 /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1663 ///
1664 /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1665 /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1666 /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1667 /// assert_eq!(corners_in_pixels.bottom_right, Pixels(20.0).min(Pixels(25.0))); // Clamped to 25.0
1668 /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped
1669 /// ```
1670 pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1671 let max = size.width.max(size.height) / 2.;
1672 Corners {
1673 top_left: self.top_left.to_pixels(rem_size).min(max),
1674 top_right: self.top_right.to_pixels(rem_size).min(max),
1675 bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1676 bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1677 }
1678 }
1679}
1680
1681impl Corners<Pixels> {
1682 /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1683 ///
1684 /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1685 ///
1686 /// # Arguments
1687 ///
1688 /// * `factor` - The scaling factor to apply to each corner.
1689 ///
1690 /// # Returns
1691 ///
1692 /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1693 ///
1694 /// # Examples
1695 ///
1696 /// ```
1697 /// # use zed::{Corners, Pixels};
1698 /// let corners = Corners {
1699 /// top_left: Pixels(10.0),
1700 /// top_right: Pixels(20.0),
1701 /// bottom_right: Pixels(30.0),
1702 /// bottom_left: Pixels(40.0),
1703 /// };
1704 /// let scaled_corners = corners.scale(2.0);
1705 /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1706 /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1707 /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1708 /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1709 /// ```
1710 pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1711 Corners {
1712 top_left: self.top_left.scale(factor),
1713 top_right: self.top_right.scale(factor),
1714 bottom_right: self.bottom_right.scale(factor),
1715 bottom_left: self.bottom_left.scale(factor),
1716 }
1717 }
1718
1719 /// Returns the maximum value of any corner.
1720 ///
1721 /// # Returns
1722 ///
1723 /// The maximum `Pixels` value among all four corners.
1724 pub fn max(&self) -> Pixels {
1725 self.top_left
1726 .max(self.top_right)
1727 .max(self.bottom_right)
1728 .max(self.bottom_left)
1729 }
1730}
1731
1732impl<T: Clone + Default + Debug> Corners<T> {
1733 /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
1734 ///
1735 /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
1736 /// that defines how to convert between the two types. The closure is applied to each field
1737 /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
1738 ///
1739 /// # Arguments
1740 ///
1741 /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1742 ///
1743 /// # Returns
1744 ///
1745 /// Returns a new `Corners<U>` with each field mapped by the provided function.
1746 ///
1747 /// # Examples
1748 ///
1749 /// ```
1750 /// # use zed::{Corners, Pixels};
1751 /// let corners = Corners {
1752 /// top_left: Pixels(10.0),
1753 /// top_right: Pixels(20.0),
1754 /// bottom_right: Pixels(30.0),
1755 /// bottom_left: Pixels(40.0),
1756 /// };
1757 /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
1758 /// assert_eq!(corners_in_rems, Corners {
1759 /// top_left: Rems(0.625),
1760 /// top_right: Rems(1.25),
1761 /// bottom_right: Rems(1.875),
1762 /// bottom_left: Rems(2.5),
1763 /// });
1764 /// ```
1765 pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
1766 where
1767 U: Clone + Default + Debug,
1768 {
1769 Corners {
1770 top_left: f(&self.top_left),
1771 top_right: f(&self.top_right),
1772 bottom_right: f(&self.bottom_right),
1773 bottom_left: f(&self.bottom_left),
1774 }
1775 }
1776}
1777
1778impl<T> Mul for Corners<T>
1779where
1780 T: Mul<Output = T> + Clone + Default + Debug,
1781{
1782 type Output = Self;
1783
1784 fn mul(self, rhs: Self) -> Self::Output {
1785 Self {
1786 top_left: self.top_left.clone() * rhs.top_left,
1787 top_right: self.top_right.clone() * rhs.top_right,
1788 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
1789 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
1790 }
1791 }
1792}
1793
1794impl<T, S> MulAssign<S> for Corners<T>
1795where
1796 T: Mul<S, Output = T> + Clone + Default + Debug,
1797 S: Clone,
1798{
1799 fn mul_assign(&mut self, rhs: S) {
1800 self.top_left = self.top_left.clone() * rhs.clone();
1801 self.top_right = self.top_right.clone() * rhs.clone();
1802 self.bottom_right = self.bottom_right.clone() * rhs.clone();
1803 self.bottom_left = self.bottom_left.clone() * rhs;
1804 }
1805}
1806
1807impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
1808
1809impl From<f32> for Corners<Pixels> {
1810 fn from(val: f32) -> Self {
1811 Corners {
1812 top_left: val.into(),
1813 top_right: val.into(),
1814 bottom_right: val.into(),
1815 bottom_left: val.into(),
1816 }
1817 }
1818}
1819
1820impl From<Pixels> for Corners<Pixels> {
1821 fn from(val: Pixels) -> Self {
1822 Corners {
1823 top_left: val,
1824 top_right: val,
1825 bottom_right: val,
1826 bottom_left: val,
1827 }
1828 }
1829}
1830
1831/// Represents a length in pixels, the base unit of measurement in the UI framework.
1832///
1833/// `Pixels` is a value type that represents an absolute length in pixels, which is used
1834/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
1835/// of measurement for all visual elements and layout calculations.
1836///
1837/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
1838/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
1839/// is typically rounded to the nearest integer.
1840///
1841/// # Examples
1842///
1843/// ```
1844/// use zed::Pixels;
1845///
1846/// // Define a length of 10 pixels
1847/// let length = Pixels(10.0);
1848///
1849/// // Define a length and scale it by a factor of 2
1850/// let scaled_length = length.scale(2.0);
1851/// assert_eq!(scaled_length, Pixels(20.0));
1852/// ```
1853#[derive(
1854 Clone,
1855 Copy,
1856 Default,
1857 Add,
1858 AddAssign,
1859 Sub,
1860 SubAssign,
1861 Neg,
1862 Div,
1863 DivAssign,
1864 PartialEq,
1865 Serialize,
1866 Deserialize,
1867)]
1868#[repr(transparent)]
1869pub struct Pixels(pub f32);
1870
1871impl std::ops::Div for Pixels {
1872 type Output = f32;
1873
1874 fn div(self, rhs: Self) -> Self::Output {
1875 self.0 / rhs.0
1876 }
1877}
1878
1879impl std::ops::DivAssign for Pixels {
1880 fn div_assign(&mut self, rhs: Self) {
1881 *self = Self(self.0 / rhs.0);
1882 }
1883}
1884
1885impl std::ops::RemAssign for Pixels {
1886 fn rem_assign(&mut self, rhs: Self) {
1887 self.0 %= rhs.0;
1888 }
1889}
1890
1891impl std::ops::Rem for Pixels {
1892 type Output = Self;
1893
1894 fn rem(self, rhs: Self) -> Self {
1895 Self(self.0 % rhs.0)
1896 }
1897}
1898
1899impl Mul<f32> for Pixels {
1900 type Output = Pixels;
1901
1902 fn mul(self, other: f32) -> Pixels {
1903 Pixels(self.0 * other)
1904 }
1905}
1906
1907impl Mul<usize> for Pixels {
1908 type Output = Pixels;
1909
1910 fn mul(self, other: usize) -> Pixels {
1911 Pixels(self.0 * other as f32)
1912 }
1913}
1914
1915impl Mul<Pixels> for f32 {
1916 type Output = Pixels;
1917
1918 fn mul(self, rhs: Pixels) -> Self::Output {
1919 Pixels(self * rhs.0)
1920 }
1921}
1922
1923impl MulAssign<f32> for Pixels {
1924 fn mul_assign(&mut self, other: f32) {
1925 self.0 *= other;
1926 }
1927}
1928
1929impl Pixels {
1930 /// Represents zero pixels.
1931 pub const ZERO: Pixels = Pixels(0.0);
1932 /// The maximum value that can be represented by `Pixels`.
1933 pub const MAX: Pixels = Pixels(f32::MAX);
1934
1935 /// Floors the `Pixels` value to the nearest whole number.
1936 ///
1937 /// # Returns
1938 ///
1939 /// Returns a new `Pixels` instance with the floored value.
1940 pub fn floor(&self) -> Self {
1941 Self(self.0.floor())
1942 }
1943
1944 /// Rounds the `Pixels` value to the nearest whole number.
1945 ///
1946 /// # Returns
1947 ///
1948 /// Returns a new `Pixels` instance with the rounded value.
1949 pub fn round(&self) -> Self {
1950 Self(self.0.round())
1951 }
1952
1953 /// Returns the ceiling of the `Pixels` value to the nearest whole number.
1954 ///
1955 /// # Returns
1956 ///
1957 /// Returns a new `Pixels` instance with the ceiling value.
1958 pub fn ceil(&self) -> Self {
1959 Self(self.0.ceil())
1960 }
1961
1962 /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
1963 ///
1964 /// This method is used when adjusting pixel values for display scaling factors,
1965 /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
1966 /// thus requires scaling to maintain visual consistency and readability.
1967 ///
1968 /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
1969 /// calculations where display scaling is considered.
1970 pub fn scale(&self, factor: f32) -> ScaledPixels {
1971 ScaledPixels(self.0 * factor)
1972 }
1973
1974 /// Raises the `Pixels` value to a given power.
1975 ///
1976 /// # Arguments
1977 ///
1978 /// * `exponent` - The exponent to raise the `Pixels` value by.
1979 ///
1980 /// # Returns
1981 ///
1982 /// Returns a new `Pixels` instance with the value raised to the given exponent.
1983 pub fn pow(&self, exponent: f32) -> Self {
1984 Self(self.0.powf(exponent))
1985 }
1986
1987 /// Returns the absolute value of the `Pixels`.
1988 ///
1989 /// # Returns
1990 ///
1991 /// A new `Pixels` instance with the absolute value of the original `Pixels`.
1992 pub fn abs(&self) -> Self {
1993 Self(self.0.abs())
1994 }
1995}
1996
1997impl Mul<Pixels> for Pixels {
1998 type Output = Pixels;
1999
2000 fn mul(self, rhs: Pixels) -> Self::Output {
2001 Pixels(self.0 * rhs.0)
2002 }
2003}
2004
2005impl Eq for Pixels {}
2006
2007impl PartialOrd for Pixels {
2008 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2009 self.0.partial_cmp(&other.0)
2010 }
2011}
2012
2013impl Ord for Pixels {
2014 fn cmp(&self, other: &Self) -> cmp::Ordering {
2015 self.partial_cmp(other).unwrap()
2016 }
2017}
2018
2019impl std::hash::Hash for Pixels {
2020 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2021 self.0.to_bits().hash(state);
2022 }
2023}
2024
2025impl From<f64> for Pixels {
2026 fn from(pixels: f64) -> Self {
2027 Pixels(pixels as f32)
2028 }
2029}
2030
2031impl From<f32> for Pixels {
2032 fn from(pixels: f32) -> Self {
2033 Pixels(pixels)
2034 }
2035}
2036
2037impl Debug for Pixels {
2038 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2039 write!(f, "{} px", self.0)
2040 }
2041}
2042
2043impl From<Pixels> for f32 {
2044 fn from(pixels: Pixels) -> Self {
2045 pixels.0
2046 }
2047}
2048
2049impl From<&Pixels> for f32 {
2050 fn from(pixels: &Pixels) -> Self {
2051 pixels.0
2052 }
2053}
2054
2055impl From<Pixels> for f64 {
2056 fn from(pixels: Pixels) -> Self {
2057 pixels.0 as f64
2058 }
2059}
2060
2061impl From<Pixels> for u32 {
2062 fn from(pixels: Pixels) -> Self {
2063 pixels.0 as u32
2064 }
2065}
2066
2067impl From<u32> for Pixels {
2068 fn from(pixels: u32) -> Self {
2069 Pixels(pixels as f32)
2070 }
2071}
2072
2073impl From<Pixels> for usize {
2074 fn from(pixels: Pixels) -> Self {
2075 pixels.0 as usize
2076 }
2077}
2078
2079impl From<usize> for Pixels {
2080 fn from(pixels: usize) -> Self {
2081 Pixels(pixels as f32)
2082 }
2083}
2084
2085/// Represents physical pixels on the display.
2086///
2087/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2088/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2089/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2090/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2091/// display.
2092#[derive(
2093 Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
2094)]
2095#[repr(transparent)]
2096pub struct DevicePixels(pub(crate) i32);
2097
2098impl DevicePixels {
2099 /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2100 ///
2101 /// This function is useful when working with graphical data that needs to be stored in a buffer,
2102 /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2103 ///
2104 /// # Arguments
2105 ///
2106 /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2107 ///
2108 /// # Returns
2109 ///
2110 /// The number of bytes required to represent the `DevicePixels` value in memory.
2111 ///
2112 /// # Examples
2113 ///
2114 /// ```
2115 /// # use zed::DevicePixels;
2116 /// let pixels = DevicePixels(10); // 10 device pixels
2117 /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2118 /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2119 /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2120 /// ```
2121 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2122 self.0 as u32 * bytes_per_pixel as u32
2123 }
2124}
2125
2126impl fmt::Debug for DevicePixels {
2127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2128 write!(f, "{} px (device)", self.0)
2129 }
2130}
2131
2132impl From<DevicePixels> for i32 {
2133 fn from(device_pixels: DevicePixels) -> Self {
2134 device_pixels.0
2135 }
2136}
2137
2138impl From<i32> for DevicePixels {
2139 fn from(device_pixels: i32) -> Self {
2140 DevicePixels(device_pixels)
2141 }
2142}
2143
2144impl From<u32> for DevicePixels {
2145 fn from(device_pixels: u32) -> Self {
2146 DevicePixels(device_pixels as i32)
2147 }
2148}
2149
2150impl From<DevicePixels> for u32 {
2151 fn from(device_pixels: DevicePixels) -> Self {
2152 device_pixels.0 as u32
2153 }
2154}
2155
2156impl From<DevicePixels> for u64 {
2157 fn from(device_pixels: DevicePixels) -> Self {
2158 device_pixels.0 as u64
2159 }
2160}
2161
2162impl From<u64> for DevicePixels {
2163 fn from(device_pixels: u64) -> Self {
2164 DevicePixels(device_pixels as i32)
2165 }
2166}
2167
2168impl From<DevicePixels> for usize {
2169 fn from(device_pixels: DevicePixels) -> Self {
2170 device_pixels.0 as usize
2171 }
2172}
2173
2174impl From<usize> for DevicePixels {
2175 fn from(device_pixels: usize) -> Self {
2176 DevicePixels(device_pixels as i32)
2177 }
2178}
2179
2180/// Represents scaled pixels that take into account the device's scale factor.
2181///
2182/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2183/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2184/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2185/// dimensions and positions can be specified in a way that scales appropriately across different
2186/// display resolutions.
2187#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2188#[repr(transparent)]
2189pub struct ScaledPixels(pub(crate) f32);
2190
2191impl ScaledPixels {
2192 /// Floors the `ScaledPixels` value to the nearest whole number.
2193 ///
2194 /// # Returns
2195 ///
2196 /// Returns a new `ScaledPixels` instance with the floored value.
2197 pub fn floor(&self) -> Self {
2198 Self(self.0.floor())
2199 }
2200
2201 /// Rounds the `ScaledPixels` value to the nearest whole number.
2202 ///
2203 /// # Returns
2204 ///
2205 /// Returns a new `ScaledPixels` instance with the rounded value.
2206 pub fn ceil(&self) -> Self {
2207 Self(self.0.ceil())
2208 }
2209}
2210
2211impl Eq for ScaledPixels {}
2212
2213impl Debug for ScaledPixels {
2214 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2215 write!(f, "{} px (scaled)", self.0)
2216 }
2217}
2218
2219impl From<ScaledPixels> for DevicePixels {
2220 fn from(scaled: ScaledPixels) -> Self {
2221 DevicePixels(scaled.0.ceil() as i32)
2222 }
2223}
2224
2225impl From<DevicePixels> for ScaledPixels {
2226 fn from(device: DevicePixels) -> Self {
2227 ScaledPixels(device.0 as f32)
2228 }
2229}
2230
2231impl From<ScaledPixels> for f64 {
2232 fn from(scaled_pixels: ScaledPixels) -> Self {
2233 scaled_pixels.0 as f64
2234 }
2235}
2236
2237/// Represents pixels in a global coordinate space, which can span across multiple displays.
2238///
2239/// `GlobalPixels` is used when dealing with a coordinate system that is not limited to a single
2240/// display's boundaries. This type is particularly useful in multi-monitor setups where
2241/// positioning and measurements need to be consistent and relative to a "global" origin point
2242/// rather than being relative to any individual display.
2243#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2244#[repr(transparent)]
2245pub struct GlobalPixels(pub(crate) f32);
2246
2247impl Debug for GlobalPixels {
2248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2249 write!(f, "{} px (global coordinate space)", self.0)
2250 }
2251}
2252
2253impl From<GlobalPixels> for f64 {
2254 fn from(global_pixels: GlobalPixels) -> Self {
2255 global_pixels.0 as f64
2256 }
2257}
2258
2259impl From<f64> for GlobalPixels {
2260 fn from(global_pixels: f64) -> Self {
2261 GlobalPixels(global_pixels as f32)
2262 }
2263}
2264
2265/// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`WindowContext::set_rem_size`][set_rem_size].
2266///
2267/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2268/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2269/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2270/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2271///
2272/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2273///
2274/// [set_rem_size]: crate::WindowContext::set_rem_size
2275#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2276pub struct Rems(pub f32);
2277
2278impl Mul<Pixels> for Rems {
2279 type Output = Pixels;
2280
2281 fn mul(self, other: Pixels) -> Pixels {
2282 Pixels(self.0 * other.0)
2283 }
2284}
2285
2286impl Debug for Rems {
2287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2288 write!(f, "{} rem", self.0)
2289 }
2290}
2291
2292/// Represents an absolute length in pixels or rems.
2293///
2294/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2295/// affected by the current font size, or a number of rems, which is relative to the font size of
2296/// the root element. It is used for specifying dimensions that are either independent of or
2297/// related to the typographic scale.
2298#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2299pub enum AbsoluteLength {
2300 /// A length in pixels.
2301 Pixels(Pixels),
2302 /// A length in rems.
2303 Rems(Rems),
2304}
2305
2306impl AbsoluteLength {
2307 /// Checks if the absolute length is zero.
2308 pub fn is_zero(&self) -> bool {
2309 match self {
2310 AbsoluteLength::Pixels(px) => px.0 == 0.0,
2311 AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2312 }
2313 }
2314}
2315
2316impl From<Pixels> for AbsoluteLength {
2317 fn from(pixels: Pixels) -> Self {
2318 AbsoluteLength::Pixels(pixels)
2319 }
2320}
2321
2322impl From<Rems> for AbsoluteLength {
2323 fn from(rems: Rems) -> Self {
2324 AbsoluteLength::Rems(rems)
2325 }
2326}
2327
2328impl AbsoluteLength {
2329 /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2330 ///
2331 /// # Arguments
2332 ///
2333 /// * `rem_size` - The size of one rem in pixels.
2334 ///
2335 /// # Returns
2336 ///
2337 /// Returns the `AbsoluteLength` as `Pixels`.
2338 ///
2339 /// # Examples
2340 ///
2341 /// ```
2342 /// # use zed::{AbsoluteLength, Pixels};
2343 /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2344 /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2345 /// let rem_size = Pixels(16.0);
2346 ///
2347 /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2348 /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2349 /// ```
2350 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2351 match self {
2352 AbsoluteLength::Pixels(pixels) => *pixels,
2353 AbsoluteLength::Rems(rems) => *rems * rem_size,
2354 }
2355 }
2356}
2357
2358impl Default for AbsoluteLength {
2359 fn default() -> Self {
2360 px(0.).into()
2361 }
2362}
2363
2364/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2365///
2366/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2367/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2368/// fraction of the parent's size.
2369#[derive(Clone, Copy, Neg, PartialEq)]
2370pub enum DefiniteLength {
2371 /// An absolute length specified in pixels or rems.
2372 Absolute(AbsoluteLength),
2373 /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2374 Fraction(f32),
2375}
2376
2377impl DefiniteLength {
2378 /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2379 ///
2380 /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2381 /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2382 ///
2383 /// # Arguments
2384 ///
2385 /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2386 /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2387 ///
2388 /// # Returns
2389 ///
2390 /// Returns the `DefiniteLength` as `Pixels`.
2391 ///
2392 /// # Examples
2393 ///
2394 /// ```
2395 /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2396 /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2397 /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2398 /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2399 /// let base_size = AbsoluteLength::Pixels(px(100.0));
2400 /// let rem_size = px(16.0);
2401 ///
2402 /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2403 /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2404 /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2405 /// ```
2406 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2407 match self {
2408 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2409 DefiniteLength::Fraction(fraction) => match base_size {
2410 AbsoluteLength::Pixels(px) => px * *fraction,
2411 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2412 },
2413 }
2414 }
2415}
2416
2417impl Debug for DefiniteLength {
2418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2419 match self {
2420 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2421 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2422 }
2423 }
2424}
2425
2426impl From<Pixels> for DefiniteLength {
2427 fn from(pixels: Pixels) -> Self {
2428 Self::Absolute(pixels.into())
2429 }
2430}
2431
2432impl From<Rems> for DefiniteLength {
2433 fn from(rems: Rems) -> Self {
2434 Self::Absolute(rems.into())
2435 }
2436}
2437
2438impl From<AbsoluteLength> for DefiniteLength {
2439 fn from(length: AbsoluteLength) -> Self {
2440 Self::Absolute(length)
2441 }
2442}
2443
2444impl Default for DefiniteLength {
2445 fn default() -> Self {
2446 Self::Absolute(AbsoluteLength::default())
2447 }
2448}
2449
2450/// A length that can be defined in pixels, rems, percent of parent, or auto.
2451#[derive(Clone, Copy)]
2452pub enum Length {
2453 /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2454 Definite(DefiniteLength),
2455 /// An automatic length that is determined by the context in which it is used.
2456 Auto,
2457}
2458
2459impl Debug for Length {
2460 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2461 match self {
2462 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2463 Length::Auto => write!(f, "auto"),
2464 }
2465 }
2466}
2467
2468/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2469///
2470/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2471/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2472///
2473/// # Arguments
2474///
2475/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2476///
2477/// # Returns
2478///
2479/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2480pub fn relative(fraction: f32) -> DefiniteLength {
2481 DefiniteLength::Fraction(fraction)
2482}
2483
2484/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2485pub fn phi() -> DefiniteLength {
2486 relative(1.618_034)
2487}
2488
2489/// Constructs a `Rems` value representing a length in rems.
2490///
2491/// # Arguments
2492///
2493/// * `rems` - The number of rems for the length.
2494///
2495/// # Returns
2496///
2497/// A `Rems` representing the specified number of rems.
2498pub fn rems(rems: f32) -> Rems {
2499 Rems(rems)
2500}
2501
2502/// Constructs a `Pixels` value representing a length in pixels.
2503///
2504/// # Arguments
2505///
2506/// * `pixels` - The number of pixels for the length.
2507///
2508/// # Returns
2509///
2510/// A `Pixels` representing the specified number of pixels.
2511pub const fn px(pixels: f32) -> Pixels {
2512 Pixels(pixels)
2513}
2514
2515/// Returns a `Length` representing an automatic length.
2516///
2517/// The `auto` length is often used in layout calculations where the length should be determined
2518/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2519/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2520/// to instruct the layout engine to calculate the size based on other factors like the size of the
2521/// container or the intrinsic size of the content.
2522///
2523/// # Returns
2524///
2525/// A `Length` variant set to `Auto`.
2526pub fn auto() -> Length {
2527 Length::Auto
2528}
2529
2530impl From<Pixels> for Length {
2531 fn from(pixels: Pixels) -> Self {
2532 Self::Definite(pixels.into())
2533 }
2534}
2535
2536impl From<Rems> for Length {
2537 fn from(rems: Rems) -> Self {
2538 Self::Definite(rems.into())
2539 }
2540}
2541
2542impl From<DefiniteLength> for Length {
2543 fn from(length: DefiniteLength) -> Self {
2544 Self::Definite(length)
2545 }
2546}
2547
2548impl From<AbsoluteLength> for Length {
2549 fn from(length: AbsoluteLength) -> Self {
2550 Self::Definite(length.into())
2551 }
2552}
2553
2554impl Default for Length {
2555 fn default() -> Self {
2556 Self::Definite(DefiniteLength::default())
2557 }
2558}
2559
2560impl From<()> for Length {
2561 fn from(_: ()) -> Self {
2562 Self::Definite(DefiniteLength::default())
2563 }
2564}
2565
2566/// Provides a trait for types that can calculate half of their value.
2567///
2568/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2569/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2570/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2571pub trait Half {
2572 /// Returns half of the current value.
2573 ///
2574 /// # Returns
2575 ///
2576 /// A new instance of the implementing type, representing half of the original value.
2577 fn half(&self) -> Self;
2578}
2579
2580impl Half for f32 {
2581 fn half(&self) -> Self {
2582 self / 2.
2583 }
2584}
2585
2586impl Half for DevicePixels {
2587 fn half(&self) -> Self {
2588 Self(self.0 / 2)
2589 }
2590}
2591
2592impl Half for ScaledPixels {
2593 fn half(&self) -> Self {
2594 Self(self.0 / 2.)
2595 }
2596}
2597
2598impl Half for Pixels {
2599 fn half(&self) -> Self {
2600 Self(self.0 / 2.)
2601 }
2602}
2603
2604impl Half for Rems {
2605 fn half(&self) -> Self {
2606 Self(self.0 / 2.)
2607 }
2608}
2609
2610impl Half for GlobalPixels {
2611 fn half(&self) -> Self {
2612 Self(self.0 / 2.)
2613 }
2614}
2615
2616/// A trait for checking if a value is zero.
2617///
2618/// This trait provides a method to determine if a value is considered to be zero.
2619/// It is implemented for various numeric and length-related types where the concept
2620/// of zero is applicable. This can be useful for comparisons, optimizations, or
2621/// determining if an operation has a neutral effect.
2622pub trait IsZero {
2623 /// Determines if the value is zero.
2624 ///
2625 /// # Returns
2626 ///
2627 /// Returns `true` if the value is zero, `false` otherwise.
2628 fn is_zero(&self) -> bool;
2629}
2630
2631impl IsZero for DevicePixels {
2632 fn is_zero(&self) -> bool {
2633 self.0 == 0
2634 }
2635}
2636
2637impl IsZero for ScaledPixels {
2638 fn is_zero(&self) -> bool {
2639 self.0 == 0.
2640 }
2641}
2642
2643impl IsZero for Pixels {
2644 fn is_zero(&self) -> bool {
2645 self.0 == 0.
2646 }
2647}
2648
2649impl IsZero for Rems {
2650 fn is_zero(&self) -> bool {
2651 self.0 == 0.
2652 }
2653}
2654
2655impl IsZero for AbsoluteLength {
2656 fn is_zero(&self) -> bool {
2657 match self {
2658 AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
2659 AbsoluteLength::Rems(rems) => rems.is_zero(),
2660 }
2661 }
2662}
2663
2664impl IsZero for DefiniteLength {
2665 fn is_zero(&self) -> bool {
2666 match self {
2667 DefiniteLength::Absolute(length) => length.is_zero(),
2668 DefiniteLength::Fraction(fraction) => *fraction == 0.,
2669 }
2670 }
2671}
2672
2673impl IsZero for Length {
2674 fn is_zero(&self) -> bool {
2675 match self {
2676 Length::Definite(length) => length.is_zero(),
2677 Length::Auto => false,
2678 }
2679 }
2680}
2681
2682impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
2683 fn is_zero(&self) -> bool {
2684 self.x.is_zero() && self.y.is_zero()
2685 }
2686}
2687
2688impl<T> IsZero for Size<T>
2689where
2690 T: IsZero + Default + Debug + Clone,
2691{
2692 fn is_zero(&self) -> bool {
2693 self.width.is_zero() || self.height.is_zero()
2694 }
2695}
2696
2697impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
2698 fn is_zero(&self) -> bool {
2699 self.size.is_zero()
2700 }
2701}
2702
2703impl<T> IsZero for Corners<T>
2704where
2705 T: IsZero + Clone + Default + Debug,
2706{
2707 fn is_zero(&self) -> bool {
2708 self.top_left.is_zero()
2709 && self.top_right.is_zero()
2710 && self.bottom_right.is_zero()
2711 && self.bottom_left.is_zero()
2712 }
2713}
2714
2715#[cfg(test)]
2716mod tests {
2717 use super::*;
2718
2719 #[test]
2720 fn test_bounds_intersects() {
2721 let bounds1 = Bounds {
2722 origin: Point { x: 0.0, y: 0.0 },
2723 size: Size {
2724 width: 5.0,
2725 height: 5.0,
2726 },
2727 };
2728 let bounds2 = Bounds {
2729 origin: Point { x: 4.0, y: 4.0 },
2730 size: Size {
2731 width: 5.0,
2732 height: 5.0,
2733 },
2734 };
2735 let bounds3 = Bounds {
2736 origin: Point { x: 10.0, y: 10.0 },
2737 size: Size {
2738 width: 5.0,
2739 height: 5.0,
2740 },
2741 };
2742
2743 // Test Case 1: Intersecting bounds
2744 assert_eq!(bounds1.intersects(&bounds2), true);
2745
2746 // Test Case 2: Non-Intersecting bounds
2747 assert_eq!(bounds1.intersects(&bounds3), false);
2748
2749 // Test Case 3: Bounds intersecting with themselves
2750 assert_eq!(bounds1.intersects(&bounds1), true);
2751 }
2752}