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