Created
August 6, 2024 21:06
-
-
Save airstrike/6e48e042f050a1959939e023ba52e014 to your computer and use it in GitHub Desktop.
Smart Rectangles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! Rectangles of every kind! Assumes negative sizes imply that the Rectangle | |
//! was drawn from bottom to top, right to left, or both. | |
use iced::{Point, Rectangle, Size}; | |
/// Creates a `Rectangle` that ensures positive dimensions. | |
/// | |
/// If the size is negative in either direction, it subtracts it from the | |
/// top-left coordinates accordingly and flips it to a positive sign. This way, | |
/// if a rectangle is drawn from bottom-right to top-left, it still results in a | |
/// valid geometric shape. | |
/// | |
/// # Parameters | |
/// | |
/// - `top_left`: The top-left `Point` of the rectangle. | |
/// - `size`: The `Size` of the rectangle. | |
/// | |
/// # Returns | |
/// | |
/// A `Rectangle` with positive dimensions. | |
pub fn smart_rectangle<T>(top_left: Point<T>, size: Size<T>) -> Rectangle<T> | |
where | |
T: Default | |
+ PartialOrd | |
+ Copy | |
+ std::ops::Neg<Output = T> | |
+ std::ops::Add<Output = T> | |
+ std::ops::Sub<Output = T>, | |
{ | |
let mut x = top_left.x; | |
let mut y = top_left.y; | |
let mut width = size.width; | |
let mut height = size.height; | |
// Adjust x and width if width is negative | |
if width < T::default() { | |
x = x + width; | |
width = -width; | |
} | |
// Adjust y and height if height is negative | |
if height < T::default() { | |
y = y + height; | |
height = -height; | |
} | |
Rectangle { | |
x, | |
y, | |
width, | |
height, | |
} | |
} | |
#[cfg(test)] | |
mod tests { | |
use super::*; | |
/// Tests that `smart_rectangle` correctly handles positive sizes. | |
#[test] | |
fn test_smart_rectangle_positive_size() { | |
let top_left = Point { x: 0.0, y: 0.0 }; | |
let size = Size { | |
width: 10.0, | |
height: 5.0, | |
}; | |
let rect = smart_rectangle(top_left, size); | |
assert_eq!(rect.x, 0.0); | |
assert_eq!(rect.y, 0.0); | |
assert_eq!(rect.width, 10.0); | |
assert_eq!(rect.height, 5.0); | |
} | |
/// Tests that `smart_rectangle` correctly handles negative width. | |
#[test] | |
fn test_smart_rectangle_negative_width() { | |
let top_left = Point { x: 10.0, y: 10.0 }; | |
let size = Size { | |
width: -10.0, | |
height: 5.0, | |
}; | |
let rect = smart_rectangle(top_left, size); | |
assert_eq!(rect.x, 0.0); | |
assert_eq!(rect.y, 10.0); | |
assert_eq!(rect.width, 10.0); | |
assert_eq!(rect.height, 5.0); | |
} | |
/// Tests that `smart_rectangle` correctly handles negative height. | |
#[test] | |
fn test_smart_rectangle_negative_height() { | |
let top_left = Point { x: 10.0, y: 10.0 }; | |
let size = Size { | |
width: 10.0, | |
height: -5.0, | |
}; | |
let rect = smart_rectangle(top_left, size); | |
assert_eq!(rect.x, 10.0); | |
assert_eq!(rect.y, 5.0); | |
assert_eq!(rect.width, 10.0); | |
assert_eq!(rect.height, 5.0); | |
} | |
/// Tests that `smart_rectangle` correctly handles both negative width and height. | |
#[test] | |
fn test_smart_rectangle_negative_size() { | |
let top_left = Point { x: 10.0, y: 10.0 }; | |
let size = Size { | |
width: -10.0, | |
height: -5.0, | |
}; | |
let rect = smart_rectangle(top_left, size); | |
assert_eq!(rect.x, 0.0); | |
assert_eq!(rect.y, 5.0); | |
assert_eq!(rect.width, 10.0); | |
assert_eq!(rect.height, 5.0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment