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