Add rounded_rectangle to geometry::Path

This commit is contained in:
Gints Polis 2024-07-02 23:59:24 +03:00 committed by Héctor Ramón Jiménez
parent aed59bae50
commit 7e89015e60
No known key found for this signature in database
GPG key ID: 4C07CEC81AFA161F
2 changed files with 79 additions and 2 deletions

View file

@ -9,7 +9,8 @@ pub use builder::Builder;
pub use lyon_path; pub use lyon_path;
use iced_core::{Point, Size}; use crate::core::border;
use crate::core::{Point, Size};
/// An immutable set of points that may or may not be connected. /// An immutable set of points that may or may not be connected.
/// ///
@ -47,6 +48,16 @@ impl Path {
Self::new(|p| p.rectangle(top_left, size)) Self::new(|p| p.rectangle(top_left, size))
} }
/// Creates a new [`Path`] representing a rounded rectangle given its top-left
/// corner coordinate, its [`Size`] and [`border::Radius`].
pub fn rounded_rectangle(
top_left: Point,
size: Size,
radius: border::Radius,
) -> Self {
Self::new(|p| p.rounded_rectangle(top_left, size, radius))
}
/// Creates a new [`Path`] representing a circle given its center /// Creates a new [`Path`] representing a circle given its center
/// coordinate and its radius. /// coordinate and its radius.
pub fn circle(center: Point, radius: f32) -> Self { pub fn circle(center: Point, radius: f32) -> Self {

View file

@ -1,6 +1,7 @@
use crate::geometry::path::{arc, Arc, Path}; use crate::geometry::path::{arc, Arc, Path};
use iced_core::{Point, Radians, Size}; use crate::core::border;
use crate::core::{Point, Radians, Size};
use lyon_path::builder::{self, SvgPathBuilder}; use lyon_path::builder::{self, SvgPathBuilder};
use lyon_path::geom; use lyon_path::geom;
@ -160,6 +161,71 @@ impl Builder {
self.close(); self.close();
} }
/// Adds a rounded rectangle to the [`Path`] given its top-left
/// corner coordinate its [`Size`] and [`border::Radius`].
#[inline]
pub fn rounded_rectangle(
&mut self,
top_left: Point,
size: Size,
radius: border::Radius,
) {
let min_size = (size.height / 2.0).min(size.width / 2.0);
let [top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner] =
radius.into();
self.move_to(Point::new(
top_left.x + min_size.min(top_left_corner),
top_left.y,
));
self.line_to(Point::new(
top_left.x + size.width - min_size.min(top_right_corner),
top_left.y,
));
self.arc_to(
Point::new(top_left.x + size.width, top_left.y),
Point::new(
top_left.x + size.width,
top_left.y + min_size.min(top_right_corner),
),
min_size.min(top_right_corner),
);
self.line_to(Point::new(
top_left.x + size.width,
top_left.y + size.height - min_size.min(bottom_right_corner),
));
self.arc_to(
Point::new(top_left.x + size.width, top_left.y + size.height),
Point::new(
top_left.x + size.width - min_size.min(bottom_right_corner),
top_left.y + size.height,
),
min_size.min(bottom_right_corner),
);
self.line_to(Point::new(
top_left.x + min_size.min(bottom_left_corner),
top_left.y + size.height,
));
self.arc_to(
Point::new(top_left.x, top_left.y + size.height),
Point::new(
top_left.x,
top_left.y + size.height - min_size.min(bottom_left_corner),
),
min_size.min(bottom_left_corner),
);
self.line_to(Point::new(
top_left.x,
top_left.y + min_size.min(top_left_corner),
));
self.arc_to(
Point::new(top_left.x, top_left.y),
Point::new(top_left.x + min_size.min(top_left_corner), top_left.y),
min_size.min(top_left_corner),
);
self.close();
}
/// Adds a circle to the [`Path`] given its center coordinate and its /// Adds a circle to the [`Path`] given its center coordinate and its
/// radius. /// radius.
#[inline] #[inline]