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