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