nannou_core/geom/
rect.rs

1use crate::geom::{quad, scalar, Align, Edge, Point2, Quad, Range, Scalar, Tri};
2use crate::glam::{DVec2, Vec2};
3use crate::math::{self, num_traits::Float};
4use core::ops::Neg;
5
6/// Defines a Rectangle's bounds across the x and y axes.
7#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
8pub struct Rect<S = scalar::Default> {
9    /// The start and end positions of the Rectangle on the x axis.
10    pub x: Range<S>,
11    /// The start and end positions of the Rectangle on the y axis.
12    pub y: Range<S>,
13}
14
15/// The distance between the inner edge of a border and the outer edge of the inner content.
16#[derive(Copy, Clone, Debug, PartialEq)]
17pub struct Padding<S = scalar::Default> {
18    /// Padding on the start and end of the *x* axis.
19    pub x: Range<S>,
20    /// Padding on the start and end of the *y* axis.
21    pub y: Range<S>,
22}
23
24/// Either of the four corners of a **Rect**.
25#[derive(Copy, Clone, Debug, PartialEq, Eq)]
26pub enum Corner {
27    /// The top left corner of a **Rect**.
28    TopLeft,
29    /// The top right corner of a **Rect**.
30    TopRight,
31    /// The bottom left corner of a **Rect**.
32    BottomLeft,
33    /// The bottom right corner of a **Rect**.
34    BottomRight,
35}
36
37/// Yields even subdivisions of a `Rect`.
38///
39/// The four subdivisions will each be yielded as a `Rect` whose dimensions are exactly half of the
40/// original `Rect`.
41#[derive(Clone)]
42pub struct Subdivisions<S = scalar::Default> {
43    ranges: SubdivisionRanges<S>,
44    subdivision_index: u8,
45}
46
47/// The ranges that describe the subdivisions of a `Rect`.
48#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
49pub struct SubdivisionRanges<S = scalar::Default> {
50    /// The first half of the x range.
51    pub x_a: Range<S>,
52    /// The second half of the x range.
53    pub x_b: Range<S>,
54    /// The first half of the y range.
55    pub y_a: Range<S>,
56    /// The second half of the y range.
57    pub y_b: Range<S>,
58}
59
60/// An iterator yielding the four corners of a `Rect`.
61#[derive(Clone, Debug)]
62pub struct Corners<S = scalar::Default> {
63    rect: Rect<S>,
64    index: u8,
65}
66
67/// The triangles iterator yielded by the `Rect`.
68pub type Triangles<S> = quad::Triangles<[S; 2]>;
69
70/// The number of subdivisions when dividing a `Rect` in half along the *x* and *y* axes.
71pub const NUM_SUBDIVISIONS: u8 = 4;
72
73/// The number of subdivisions when dividing a `Rect` in half along the *x* and *y* axes.
74pub const NUM_CORNERS: u8 = 4;
75
76/// The number of triangles used to represent a `Rect`.
77pub const NUM_TRIANGLES: u8 = 2;
78
79impl<S> Padding<S>
80where
81    S: Scalar,
82{
83    /// No padding.
84    pub fn none() -> Self {
85        Padding {
86            x: Range::new(S::zero(), S::zero()),
87            y: Range::new(S::zero(), S::zero()),
88        }
89    }
90}
91
92// Given some `SubdivisionRanges` and a subdivision index, produce the rect for that subdivision.
93macro_rules! subdivision_from_index {
94    ($ranges:expr,0) => {
95        Rect {
96            x: $ranges.x_a,
97            y: $ranges.y_a,
98        }
99    };
100    ($ranges:expr,1) => {
101        Rect {
102            x: $ranges.x_b,
103            y: $ranges.y_a,
104        }
105    };
106    ($ranges:expr,2) => {
107        Rect {
108            x: $ranges.x_a,
109            y: $ranges.y_b,
110        }
111    };
112    ($ranges:expr,3) => {
113        Rect {
114            x: $ranges.x_b,
115            y: $ranges.y_b,
116        }
117    };
118}
119
120// Given some `Rect` and an index, produce the corner for that index.
121macro_rules! corner_from_index {
122    ($rect:expr,0) => {
123        [$rect.x.start, $rect.y.end]
124    };
125    ($rect:expr,1) => {
126        [$rect.x.end, $rect.y.end]
127    };
128    ($rect:expr,2) => {
129        [$rect.x.end, $rect.y.start]
130    };
131    ($rect:expr,3) => {
132        [$rect.x.start, $rect.y.start]
133    };
134}
135
136impl<S> Rect<S>
137where
138    S: Scalar + Float,
139{
140    /// Construct a Rect from the given `x` `y` coordinates and `w` `h` dimensions.
141    pub fn from_x_y_w_h(x: S, y: S, w: S, h: S) -> Self {
142        Rect {
143            x: Range::from_pos_and_len(x, w),
144            y: Range::from_pos_and_len(y, h),
145        }
146    }
147
148    /// Construct a Rect at origin with the given width and height.
149    pub fn from_w_h(w: S, h: S) -> Self {
150        Self::from_x_y_w_h(S::zero(), S::zero(), w, h)
151    }
152
153    /// The position in the middle of the x bounds.
154    pub fn x(&self) -> S {
155        self.x.middle()
156    }
157
158    /// The position in the middle of the y bounds.
159    pub fn y(&self) -> S {
160        self.y.middle()
161    }
162
163    /// The centered x and y coordinates as a tuple.
164    pub fn x_y(&self) -> (S, S) {
165        (self.x(), self.y())
166    }
167
168    /// The Rect's centered coordinates and dimensions in a tuple.
169    pub fn x_y_w_h(&self) -> (S, S, S, S) {
170        let (x, y) = self.x_y();
171        let (w, h) = self.w_h();
172        (x, y, w, h)
173    }
174
175    /// Align `self` to `other` along the *x* axis in accordance with the given `Align` variant.
176    pub fn align_x_of(self, align: Align, other: Self) -> Self {
177        Rect {
178            x: self.x.align_to(align, other.x),
179            y: self.y,
180        }
181    }
182
183    /// Align `self` to `other` along the *y* axis in accordance with the given `Align` variant.
184    pub fn align_y_of(self, align: Align, other: Self) -> Self {
185        Rect {
186            x: self.x,
187            y: self.y.align_to(align, other.y),
188        }
189    }
190
191    /// Align the middle of `self` with the middle of the `other` **Rect** along the *x* axis.
192    pub fn align_middle_x_of(self, other: Self) -> Self {
193        Rect {
194            x: self.x.align_middle_of(other.x),
195            y: self.y,
196        }
197    }
198
199    /// Align the middle of `self` with the middle of the `other` **Rect** along the *y* axis.
200    pub fn align_middle_y_of(self, other: Self) -> Self {
201        Rect {
202            x: self.x,
203            y: self.y.align_middle_of(other.y),
204        }
205    }
206
207    /// Place `self` in the middle of the top edge of the `other` **Rect**.
208    pub fn mid_top_of(self, other: Self) -> Self {
209        self.align_middle_x_of(other).align_top_of(other)
210    }
211
212    /// Place `self` in the middle of the bottom edge of the `other` **Rect**.
213    pub fn mid_bottom_of(self, other: Self) -> Self {
214        self.align_middle_x_of(other).align_bottom_of(other)
215    }
216
217    /// Place `self` in the middle of the left edge of the `other` **Rect**.
218    pub fn mid_left_of(self, other: Self) -> Self {
219        self.align_left_of(other).align_middle_y_of(other)
220    }
221
222    /// Place `self` in the middle of the right edge of the `other` **Rect**.
223    pub fn mid_right_of(self, other: Self) -> Self {
224        self.align_right_of(other).align_middle_y_of(other)
225    }
226
227    /// Place `self` directly in the middle of the `other` **Rect**.
228    pub fn middle_of(self, other: Self) -> Self {
229        self.align_middle_x_of(other).align_middle_y_of(other)
230    }
231
232    /// The four ranges used for the `Rect`'s four subdivisions.
233    pub fn subdivision_ranges(&self) -> SubdivisionRanges<S> {
234        let (x, y) = self.x_y();
235        let x_a = Range::new(self.x.start, x);
236        let x_b = Range::new(x, self.x.end);
237        let y_a = Range::new(self.y.start, y);
238        let y_b = Range::new(y, self.y.end);
239        SubdivisionRanges { x_a, x_b, y_a, y_b }
240    }
241
242    /// Divide the `Rect` in half along the *x* and *y* axes and return the four subdivisions.
243    ///
244    /// Subdivisions are yielded in the following order:
245    ///
246    /// 1. Bottom left
247    /// 2. Bottom right
248    /// 3. Top left
249    /// 4. Top right
250    pub fn subdivisions(&self) -> [Self; NUM_SUBDIVISIONS as usize] {
251        self.subdivision_ranges().rects()
252    }
253
254    /// The same as `subdivisions` but each subdivision is yielded via the returned `Iterator`.
255    pub fn subdivisions_iter(&self) -> Subdivisions<S> {
256        self.subdivision_ranges().rects_iter()
257    }
258}
259
260impl<S> Rect<S>
261where
262    S: Scalar,
263{
264    /// Construct a Rect from the coordinates of two points.
265    pub fn from_corner_points([ax, ay]: [S; 2], [bx, by]: [S; 2]) -> Self {
266        let (left, right) = if ax < bx { (ax, bx) } else { (bx, ax) };
267        let (bottom, top) = if ay < by { (ay, by) } else { (by, ay) };
268        Rect {
269            x: Range {
270                start: left,
271                end: right,
272            },
273            y: Range {
274                start: bottom,
275                end: top,
276            },
277        }
278    }
279
280    /// Converts `self` to an absolute `Rect` so that the magnitude of each range is always
281    /// positive.
282    pub fn absolute(self) -> Self {
283        let x = self.x.absolute();
284        let y = self.y.absolute();
285        Rect { x, y }
286    }
287
288    /// The Rect representing the area in which two Rects overlap.
289    pub fn overlap(self, other: Self) -> Option<Self> {
290        self.x
291            .overlap(other.x)
292            .and_then(|x| self.y.overlap(other.y).map(|y| Rect { x: x, y: y }))
293    }
294
295    /// The Rect that encompass the two given sets of Rect.
296    pub fn max(self, other: Self) -> Self
297    where
298        S: Float,
299    {
300        Rect {
301            x: self.x.max(other.x),
302            y: self.y.max(other.y),
303        }
304    }
305
306    /// The Rect's lowest y value.
307    pub fn bottom(&self) -> S {
308        self.y.absolute().start
309    }
310
311    /// The Rect's highest y value.
312    pub fn top(&self) -> S {
313        self.y.absolute().end
314    }
315
316    /// The Rect's lowest x value.
317    pub fn left(&self) -> S {
318        self.x.absolute().start
319    }
320
321    /// The Rect's highest x value.
322    pub fn right(&self) -> S {
323        self.x.absolute().end
324    }
325
326    /// The edges of the **Rect** in a tuple (left, right, bottom, top).
327    pub fn l_r_b_t(&self) -> (S, S, S, S) {
328        (self.left(), self.right(), self.bottom(), self.top())
329    }
330
331    /// Shift the Rect along the x axis.
332    pub fn shift_x(self, x: S) -> Self {
333        Rect {
334            x: self.x.shift(x),
335            ..self
336        }
337    }
338
339    /// Shift the Rect along the y axis.
340    pub fn shift_y(self, y: S) -> Self {
341        Rect {
342            y: self.y.shift(y),
343            ..self
344        }
345    }
346
347    /// Align `self`'s right edge with the left edge of the `other` **Rect**.
348    pub fn left_of(self, other: Self) -> Self {
349        Rect {
350            x: self.x.align_before(other.x),
351            y: self.y,
352        }
353    }
354
355    /// Align `self`'s left edge with the right dge of the `other` **Rect**.
356    pub fn right_of(self, other: Self) -> Self {
357        Rect {
358            x: self.x.align_after(other.x),
359            y: self.y,
360        }
361    }
362
363    /// Align `self`'s top edge with the bottom edge of the `other` **Rect**.
364    pub fn below(self, other: Self) -> Self {
365        Rect {
366            x: self.x,
367            y: self.y.align_before(other.y),
368        }
369    }
370
371    /// Align `self`'s bottom edge with the top edge of the `other` **Rect**.
372    pub fn above(self, other: Self) -> Self {
373        Rect {
374            x: self.x,
375            y: self.y.align_after(other.y),
376        }
377    }
378
379    /// Align `self`'s left edge with the left edge of the `other` **Rect**.
380    pub fn align_left_of(self, other: Self) -> Self {
381        Rect {
382            x: self.x.align_start_of(other.x),
383            y: self.y,
384        }
385    }
386
387    /// Align `self`'s right edge with the right edge of the `other` **Rect**.
388    pub fn align_right_of(self, other: Self) -> Self {
389        Rect {
390            x: self.x.align_end_of(other.x),
391            y: self.y,
392        }
393    }
394
395    /// Align `self`'s bottom edge with the bottom edge of the `other` **Rect**.
396    pub fn align_bottom_of(self, other: Self) -> Self {
397        Rect {
398            x: self.x,
399            y: self.y.align_start_of(other.y),
400        }
401    }
402
403    /// Align `self`'s top edge with the top edge of the `other` **Rect**.
404    pub fn align_top_of(self, other: Self) -> Self {
405        Rect {
406            x: self.x,
407            y: self.y.align_end_of(other.y),
408        }
409    }
410
411    /// Place `self` along the top left edges of the `other` **Rect**.
412    pub fn top_left_of(self, other: Self) -> Self {
413        self.align_left_of(other).align_top_of(other)
414    }
415
416    /// Place `self` along the top right edges of the `other` **Rect**.
417    pub fn top_right_of(self, other: Self) -> Self {
418        self.align_right_of(other).align_top_of(other)
419    }
420
421    /// Place `self` along the bottom left edges of the `other` **Rect**.
422    pub fn bottom_left_of(self, other: Self) -> Self {
423        self.align_left_of(other).align_bottom_of(other)
424    }
425
426    /// Place `self` along the bottom right edges of the `other` **Rect**.
427    pub fn bottom_right_of(self, other: Self) -> Self {
428        self.align_right_of(other).align_bottom_of(other)
429    }
430
431    /// Does the given point touch the Rectangle.
432    pub fn contains_point(self, [x, y]: [S; 2]) -> bool {
433        self.x.contains(x) && self.y.contains(y)
434    }
435
436    /// Stretches the closest edge(s) to the given point if the point lies outside of the Rect area.
437    pub fn stretch_to_point(self, [px, py]: [S; 2]) -> Self {
438        let Rect { x, y } = self;
439        Rect {
440            x: x.stretch_to_value(px),
441            y: y.stretch_to_value(py),
442        }
443    }
444
445    /// Return the **Corner** of `self` that is closest to the given **Point**.
446    pub fn closest_corner(&self, [x, y]: [S; 2]) -> Corner {
447        let x_edge = self.x.closest_edge(x);
448        let y_edge = self.y.closest_edge(y);
449        match (x_edge, y_edge) {
450            (Edge::Start, Edge::Start) => Corner::BottomLeft,
451            (Edge::Start, Edge::End) => Corner::TopLeft,
452            (Edge::End, Edge::Start) => Corner::BottomRight,
453            (Edge::End, Edge::End) => Corner::TopRight,
454        }
455    }
456
457    /// The four corners of the `Rect`.
458    pub fn corners(&self) -> Quad<[S; 2]> {
459        Quad::from([
460            corner_from_index!(self, 0),
461            corner_from_index!(self, 1),
462            corner_from_index!(self, 2),
463            corner_from_index!(self, 3),
464        ])
465    }
466
467    /// An iterator yielding the four corners of the `Rect`.
468    pub fn corners_iter(&self) -> Corners<S> {
469        let rect = *self;
470        let index = 0;
471        Corners { rect, index }
472    }
473
474    /// Return two `Tri`s that represent the `Rect`.
475    pub fn triangles(&self) -> (Tri<[S; 2]>, Tri<[S; 2]>) {
476        self.corners().triangles()
477    }
478
479    /// An iterator yielding the `Rect`'s two `Tri`'s.
480    pub fn triangles_iter(self) -> Triangles<S> {
481        self.corners().triangles_iter()
482    }
483
484    /// Produce the corner at the given index.
485    pub fn corner_at_index(&self, index: u8) -> Option<[S; 2]> {
486        match index {
487            0 => Some(corner_from_index!(self, 0)),
488            1 => Some(corner_from_index!(self, 1)),
489            2 => Some(corner_from_index!(self, 2)),
490            3 => Some(corner_from_index!(self, 3)),
491            _ => None,
492        }
493    }
494}
495
496impl Rect<f32> {
497    /// Construct a Rect from a given `Point` and `Dimensions`.
498    pub fn from_xy_wh(p: Point2, s: Vec2) -> Self {
499        Self::from_x_y_w_h(p.x, p.y, s.x, s.y)
500    }
501
502    /// Construct a Rect at origin with the given dimensions.
503    pub fn from_wh(s: Vec2) -> Self {
504        Self::from_w_h(s.x, s.y)
505    }
506
507    /// Construct a Rect from the coordinates of two points.
508    pub fn from_corners(a: Point2, b: Point2) -> Self {
509        Self::from_corner_points(a.into(), b.into())
510    }
511
512    /// The xy position in the middle of the bounds.
513    pub fn xy(&self) -> Point2 {
514        [self.x(), self.y()].into()
515    }
516
517    /// The total dimensions of the Rect.
518    pub fn wh(&self) -> Vec2 {
519        [self.w(), self.h()].into()
520    }
521
522    /// Convert the Rect to a `Point` and `Dimensions`.
523    pub fn xy_wh(&self) -> (Point2, Vec2) {
524        (self.xy(), self.wh())
525    }
526
527    /// The top left corner **Point**.
528    pub fn top_left(&self) -> Point2 {
529        [self.left(), self.top()].into()
530    }
531
532    /// The bottom left corner **Point**.
533    pub fn bottom_left(&self) -> Point2 {
534        [self.left(), self.bottom()].into()
535    }
536
537    /// The top right corner **Point**.
538    pub fn top_right(&self) -> Point2 {
539        [self.right(), self.top()].into()
540    }
541
542    /// The bottom right corner **Point**.
543    pub fn bottom_right(&self) -> Point2 {
544        [self.right(), self.bottom()].into()
545    }
546
547    /// The middle of the left edge.
548    pub fn mid_left(&self) -> Point2 {
549        [self.left(), self.y()].into()
550    }
551
552    /// The middle of the top edge.
553    pub fn mid_top(&self) -> Point2 {
554        [self.x(), self.top()].into()
555    }
556
557    /// The middle of the right edge.
558    pub fn mid_right(&self) -> Point2 {
559        [self.right(), self.y()].into()
560    }
561
562    /// The middle of the bottom edge.
563    pub fn mid_bottom(&self) -> Point2 {
564        [self.x(), self.bottom()].into()
565    }
566
567    /// Shift the Rect by the given vector.
568    pub fn shift(self, v: Vec2) -> Self {
569        self.shift_x(v.x).shift_y(v.y)
570    }
571
572    /// Does the given point touch the Rectangle.
573    pub fn contains(&self, p: Point2) -> bool {
574        self.contains_point(p.into())
575    }
576
577    /// Stretches the closest edge(s) to the given point if the point lies outside of the Rect area.
578    pub fn stretch_to(self, p: Point2) -> Self {
579        self.stretch_to_point(p.into())
580    }
581}
582
583impl Rect<f64> {
584    /// Construct a Rect from a given `Point` and `Dimensions`.
585    pub fn from_xy_wh_f64(p: DVec2, s: DVec2) -> Self {
586        Self::from_x_y_w_h(p.x, p.y, s.x, s.y)
587    }
588
589    /// Construct a Rect at origin with the given dimensions.
590    pub fn from_wh_f64(s: DVec2) -> Self {
591        Self::from_w_h(s.x, s.y)
592    }
593
594    /// Construct a Rect from the coordinates of two points.
595    pub fn from_corners_f64(a: DVec2, b: DVec2) -> Self {
596        Self::from_corner_points(a.into(), b.into())
597    }
598
599    /// The xy position in the middle of the bounds.
600    pub fn xy(&self) -> DVec2 {
601        [self.x(), self.y()].into()
602    }
603
604    /// The total dimensions of the Rect.
605    pub fn wh(&self) -> DVec2 {
606        [self.w(), self.h()].into()
607    }
608
609    /// Convert the Rect to a `Point` and `Dimensions`.
610    pub fn xy_wh(&self) -> (DVec2, DVec2) {
611        (self.xy(), self.wh())
612    }
613
614    /// The top left corner **Point**.
615    pub fn top_left(&self) -> DVec2 {
616        [self.left(), self.top()].into()
617    }
618
619    /// The bottom left corner **Point**.
620    pub fn bottom_left(&self) -> DVec2 {
621        [self.left(), self.bottom()].into()
622    }
623
624    /// The top right corner **Point**.
625    pub fn top_right(&self) -> DVec2 {
626        [self.right(), self.top()].into()
627    }
628
629    /// The bottom right corner **Point**.
630    pub fn bottom_right(&self) -> DVec2 {
631        [self.right(), self.bottom()].into()
632    }
633
634    /// The middle of the left edge.
635    pub fn mid_left(&self) -> DVec2 {
636        [self.left(), self.y()].into()
637    }
638
639    /// The middle of the top edge.
640    pub fn mid_top(&self) -> DVec2 {
641        [self.x(), self.top()].into()
642    }
643
644    /// The middle of the right edge.
645    pub fn mid_right(&self) -> DVec2 {
646        [self.right(), self.y()].into()
647    }
648
649    /// The middle of the bottom edge.
650    pub fn mid_bottom(&self) -> DVec2 {
651        [self.x(), self.bottom()].into()
652    }
653
654    /// Shift the Rect by the given vector.
655    pub fn shift(self, v: DVec2) -> Self {
656        self.shift_x(v.x).shift_y(v.y)
657    }
658
659    /// Does the given point touch the Rectangle.
660    pub fn contains(&self, p: DVec2) -> bool {
661        self.contains_point(p.into())
662    }
663
664    /// Stretches the closest edge(s) to the given point if the point lies outside of the Rect area.
665    pub fn stretch_to(self, p: DVec2) -> Self {
666        self.stretch_to_point(p.into())
667    }
668}
669
670impl<S> SubdivisionRanges<S>
671where
672    S: Copy,
673{
674    /// The `Rect`s representing each of the four subdivisions.
675    ///
676    /// Subdivisions are yielded in the following order:
677    ///
678    /// 1. Bottom left
679    /// 2. Bottom right
680    /// 3. Top left
681    /// 4. Top right
682    pub fn rects(&self) -> [Rect<S>; NUM_SUBDIVISIONS as usize] {
683        let r1 = subdivision_from_index!(self, 0);
684        let r2 = subdivision_from_index!(self, 1);
685        let r3 = subdivision_from_index!(self, 2);
686        let r4 = subdivision_from_index!(self, 3);
687        [r1, r2, r3, r4]
688    }
689
690    /// The same as `rects` but each subdivision is yielded via the returned `Iterator`.
691    pub fn rects_iter(self) -> Subdivisions<S> {
692        Subdivisions {
693            ranges: self,
694            subdivision_index: 0,
695        }
696    }
697
698    // The subdivision at the given index within the range 0..NUM_SUBDIVISIONS.
699    fn subdivision_at_index(&self, index: u8) -> Option<Rect<S>> {
700        let rect = match index {
701            0 => subdivision_from_index!(self, 0),
702            1 => subdivision_from_index!(self, 1),
703            2 => subdivision_from_index!(self, 2),
704            3 => subdivision_from_index!(self, 3),
705            _ => return None,
706        };
707        Some(rect)
708    }
709}
710
711impl<S> Rect<S>
712where
713    S: Scalar + Neg<Output = S>,
714{
715    /// The width of the Rect.
716    pub fn w(&self) -> S {
717        self.x.len()
718    }
719
720    /// The height of the Rect.
721    pub fn h(&self) -> S {
722        self.y.len()
723    }
724
725    /// The width and height of the Rect as a tuple.
726    pub fn w_h(&self) -> (S, S) {
727        (self.w(), self.h())
728    }
729
730    /// The length of the longest side of the rectangle.
731    pub fn len(&self) -> S {
732        math::partial_max(self.w(), self.h())
733    }
734
735    /// The left and top edges of the **Rect** along with the width and height.
736    pub fn l_t_w_h(&self) -> (S, S, S, S) {
737        let (w, h) = self.w_h();
738        (self.left(), self.top(), w, h)
739    }
740
741    /// The left and bottom edges of the **Rect** along with the width and height.
742    pub fn l_b_w_h(&self) -> (S, S, S, S) {
743        let (w, h) = self.w_h();
744        (self.left(), self.bottom(), w, h)
745    }
746
747    /// The Rect with some padding applied to the left edge.
748    pub fn pad_left(self, pad: S) -> Self {
749        Rect {
750            x: self.x.pad_start(pad),
751            ..self
752        }
753    }
754
755    /// The Rect with some padding applied to the right edge.
756    pub fn pad_right(self, pad: S) -> Self {
757        Rect {
758            x: self.x.pad_end(pad),
759            ..self
760        }
761    }
762
763    /// The rect with some padding applied to the bottom edge.
764    pub fn pad_bottom(self, pad: S) -> Self {
765        Rect {
766            y: self.y.pad_start(pad),
767            ..self
768        }
769    }
770
771    /// The Rect with some padding applied to the top edge.
772    pub fn pad_top(self, pad: S) -> Self {
773        Rect {
774            y: self.y.pad_end(pad),
775            ..self
776        }
777    }
778
779    /// The Rect with some padding amount applied to each edge.
780    pub fn pad(self, pad: S) -> Self {
781        let Rect { x, y } = self;
782        Rect {
783            x: x.pad(pad),
784            y: y.pad(pad),
785        }
786    }
787
788    /// The Rect with some padding applied.
789    pub fn padding(self, padding: Padding<S>) -> Self {
790        Rect {
791            x: self.x.pad_ends(padding.x.start, padding.x.end),
792            y: self.y.pad_ends(padding.y.start, padding.y.end),
793        }
794    }
795
796    /// Returns a `Rect` with a position relative to the given position on the *x* axis.
797    pub fn relative_to_x(self, x: S) -> Self {
798        Rect {
799            x: self.x.shift(-x),
800            ..self
801        }
802    }
803
804    /// Returns a `Rect` with a position relative to the given position on the *y* axis.
805    pub fn relative_to_y(self, y: S) -> Self {
806        Rect {
807            y: self.y.shift(-y),
808            ..self
809        }
810    }
811
812    /// Returns a `Rect` with a position relative to the given position.
813    pub fn relative_to(self, [x, y]: [S; 2]) -> Self {
814        self.relative_to_x(x).relative_to_y(y)
815    }
816
817    /// Invert the x axis (aka flip *around* the y axis).
818    pub fn invert_x(self) -> Self {
819        Rect {
820            x: self.x.invert(),
821            ..self
822        }
823    }
824
825    /// Invert the y axis (aka flip *around* the x axis).
826    pub fn invert_y(self) -> Self {
827        Rect {
828            y: self.y.invert(),
829            ..self
830        }
831    }
832}
833
834impl<S> Iterator for Subdivisions<S>
835where
836    S: Copy,
837{
838    type Item = Rect<S>;
839
840    fn next(&mut self) -> Option<Self::Item> {
841        if let Some(sd) = self.ranges.subdivision_at_index(self.subdivision_index) {
842            self.subdivision_index += 1;
843            return Some(sd);
844        }
845        None
846    }
847
848    fn size_hint(&self) -> (usize, Option<usize>) {
849        let len = self.len();
850        (len, Some(len))
851    }
852}
853
854impl<S> DoubleEndedIterator for Subdivisions<S>
855where
856    S: Copy,
857{
858    fn next_back(&mut self) -> Option<Self::Item> {
859        let next_index = self.subdivision_index + 1;
860        if let Some(sd) = self
861            .ranges
862            .subdivision_at_index(NUM_SUBDIVISIONS - next_index)
863        {
864            self.subdivision_index = next_index;
865            return Some(sd);
866        }
867        None
868    }
869}
870
871impl<S> ExactSizeIterator for Subdivisions<S>
872where
873    S: Copy,
874{
875    fn len(&self) -> usize {
876        NUM_SUBDIVISIONS as usize - self.subdivision_index as usize
877    }
878}
879
880impl<S> Iterator for Corners<S>
881where
882    S: Scalar,
883{
884    type Item = [S; 2];
885    fn next(&mut self) -> Option<Self::Item> {
886        if let Some(corner) = self.rect.corner_at_index(self.index) {
887            self.index += 1;
888            return Some(corner);
889        }
890        None
891    }
892
893    fn size_hint(&self) -> (usize, Option<usize>) {
894        let len = self.len();
895        (len, Some(len))
896    }
897}
898
899impl<S> DoubleEndedIterator for Corners<S>
900where
901    S: Scalar,
902{
903    fn next_back(&mut self) -> Option<Self::Item> {
904        let next_index = self.index + 1;
905        if let Some(corner) = self.rect.corner_at_index(NUM_CORNERS - next_index) {
906            self.index = next_index;
907            return Some(corner);
908        }
909        None
910    }
911}
912
913impl<S> ExactSizeIterator for Corners<S>
914where
915    S: Scalar,
916{
917    fn len(&self) -> usize {
918        (NUM_CORNERS - self.index) as usize
919    }
920}