diff options
Diffstat (limited to 'graphics/src/geometry')
-rw-r--r-- | graphics/src/geometry/frame.rs | 24 | ||||
-rw-r--r-- | graphics/src/geometry/path.rs | 13 | ||||
-rw-r--r-- | graphics/src/geometry/path/builder.rs | 68 |
3 files changed, 103 insertions, 2 deletions
diff --git a/graphics/src/geometry/frame.rs b/graphics/src/geometry/frame.rs index b5f2f139..3dee7e75 100644 --- a/graphics/src/geometry/frame.rs +++ b/graphics/src/geometry/frame.rs @@ -65,6 +65,17 @@ where self.raw.stroke(path, stroke); } + /// Draws the stroke of an axis-aligned rectangle with the provided style + /// given its top-left corner coordinate and its `Size` on the [`Frame`] . + pub fn stroke_rectangle<'a>( + &mut self, + top_left: Point, + size: Size, + stroke: impl Into<Stroke<'a>>, + ) { + self.raw.stroke_rectangle(top_left, size, stroke); + } + /// Draws the characters of the given [`Text`] on the [`Frame`], filling /// them with the given color. /// @@ -200,6 +211,12 @@ pub trait Backend: Sized { fn paste(&mut self, frame: Self); fn stroke<'a>(&mut self, path: &Path, stroke: impl Into<Stroke<'a>>); + fn stroke_rectangle<'a>( + &mut self, + top_left: Point, + size: Size, + stroke: impl Into<Stroke<'a>>, + ); fn fill(&mut self, path: &Path, fill: impl Into<Fill>); fn fill_text(&mut self, text: impl Into<Text>); @@ -248,6 +265,13 @@ impl Backend for () { fn paste(&mut self, _frame: Self) {} fn stroke<'a>(&mut self, _path: &Path, _stroke: impl Into<Stroke<'a>>) {} + fn stroke_rectangle<'a>( + &mut self, + _top_left: Point, + _size: Size, + _stroke: impl Into<Stroke<'a>>, + ) { + } fn fill(&mut self, _path: &Path, _fill: impl Into<Fill>) {} fn fill_text(&mut self, _text: impl Into<Text>) {} diff --git a/graphics/src/geometry/path.rs b/graphics/src/geometry/path.rs index 3d8fc6fa..c4f51593 100644 --- a/graphics/src/geometry/path.rs +++ b/graphics/src/geometry/path.rs @@ -9,7 +9,8 @@ pub use builder::Builder; 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. /// @@ -47,6 +48,16 @@ impl Path { 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 /// coordinate and its radius. pub fn circle(center: Point, radius: f32) -> Self { diff --git a/graphics/src/geometry/path/builder.rs b/graphics/src/geometry/path/builder.rs index 1ccd83f2..44410f6d 100644 --- a/graphics/src/geometry/path/builder.rs +++ b/graphics/src/geometry/path/builder.rs @@ -1,6 +1,7 @@ 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::geom; @@ -160,6 +161,71 @@ impl Builder { 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 /// radius. #[inline] |