summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--graphics/src/widget/canvas.rs5
-rw-r--r--graphics/src/widget/canvas/frame.rs21
-rw-r--r--native/src/user_interface.rs46
3 files changed, 52 insertions, 20 deletions
diff --git a/graphics/src/widget/canvas.rs b/graphics/src/widget/canvas.rs
index 157aa25c..65d7e37e 100644
--- a/graphics/src/widget/canvas.rs
+++ b/graphics/src/widget/canvas.rs
@@ -211,6 +211,11 @@ where
use iced_native::Renderer as _;
let bounds = layout.bounds();
+
+ if bounds.width < 1.0 || bounds.height < 1.0 {
+ return;
+ }
+
let translation = Vector::new(bounds.x, bounds.y);
let cursor = Cursor::from_window_position(cursor_position);
diff --git a/graphics/src/widget/canvas/frame.rs b/graphics/src/widget/canvas/frame.rs
index 357dfa62..a3449605 100644
--- a/graphics/src/widget/canvas/frame.rs
+++ b/graphics/src/widget/canvas/frame.rs
@@ -253,6 +253,27 @@ impl Frame {
self.transforms.current = self.transforms.previous.pop().unwrap();
}
+ /// Executes the given drawing operations within a [`Rectangle`] region,
+ /// clipping any geometry that overflows its bounds. Any transformations
+ /// performed are local to the provided closure.
+ ///
+ /// This method is useful to perform drawing operations that need to be
+ /// clipped.
+ #[inline]
+ pub fn with_clip(&mut self, region: Rectangle, f: impl FnOnce(&mut Frame)) {
+ let mut frame = Frame::new(region.size());
+
+ f(&mut frame);
+
+ self.primitives.push(Primitive::Clip {
+ bounds: region,
+ content: Box::new(Primitive::Translate {
+ translation: Vector::new(region.x, region.y),
+ content: Box::new(frame.into_geometry().into_primitive()),
+ }),
+ });
+ }
+
/// Applies a translation to the current transform of the [`Frame`].
#[inline]
pub fn translate(&mut self, translation: Vector) {
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index 00015f8b..6fc6a479 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -345,30 +345,36 @@ where
let viewport = Rectangle::with_size(self.bounds);
- if let Some(layout) = &self.overlay {
- let base_cursor = if layout.bounds().contains(cursor_position) {
- Point::new(-1.0, -1.0)
- } else {
- cursor_position
- };
+ let base_cursor = if let Some(overlay) =
+ self.root.overlay(Layout::new(&self.base), renderer)
+ {
+ let overlay_layout = self
+ .overlay
+ .take()
+ .unwrap_or_else(|| overlay.layout(renderer, self.bounds));
- self.root.widget.draw(
- renderer,
- &renderer::Style::default(),
- Layout::new(&self.base),
- base_cursor,
- &viewport,
- );
+ let new_cursor_position =
+ if overlay_layout.bounds().contains(cursor_position) {
+ Point::new(-1.0, -1.0)
+ } else {
+ cursor_position
+ };
+
+ self.overlay = Some(overlay_layout);
+
+ new_cursor_position
} else {
- self.root.widget.draw(
- renderer,
- &renderer::Style::default(),
- Layout::new(&self.base),
- cursor_position,
- &viewport,
- );
+ cursor_position
};
+ self.root.widget.draw(
+ renderer,
+ &renderer::Style::default(),
+ Layout::new(&self.base),
+ base_cursor,
+ &viewport,
+ );
+
let base_interaction = self.root.widget.mouse_interaction(
Layout::new(&self.base),
cursor_position,