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