diff options
author | 2021-10-28 16:43:16 +0700 | |
---|---|---|
committer | 2021-10-28 16:43:16 +0700 | |
commit | 9c7e340b28d11ede50b494f5341acd94673feb5d (patch) | |
tree | ddbb278a6839571334ebc3be55828c405af47e44 /native/src/user_interface.rs | |
parent | 081f2c1e1a65a084326d5f7f9bbce68440369308 (diff) | |
download | iced-9c7e340b28d11ede50b494f5341acd94673feb5d.tar.gz iced-9c7e340b28d11ede50b494f5341acd94673feb5d.tar.bz2 iced-9c7e340b28d11ede50b494f5341acd94673feb5d.zip |
Fix overlay layering in `UserInterface::draw`
... by properly implementing the Painter's algorithm.
Diffstat (limited to 'native/src/user_interface.rs')
-rw-r--r-- | native/src/user_interface.rs | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index c3a8394c..ac7fa367 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -341,7 +341,7 @@ where let viewport = Rectangle::with_size(self.bounds); - let overlay = if let Some(mut overlay) = + if let Some(mut overlay) = self.root.overlay(Layout::new(&self.base.layout)) { let layer = Self::overlay_layer( @@ -351,32 +351,12 @@ where renderer, ); - let mouse_interaction = overlay.mouse_interaction( - Layout::new(&layer.layout), - &viewport, - cursor_position, - ); - - let overlay_bounds = layer.layout.bounds(); - - renderer.with_layer(overlay_bounds, |renderer| { - overlay.draw( - renderer, - &renderer::Style::default(), - Layout::new(&layer.layout), - cursor_position, - ); - }); - self.overlay = Some(layer); - - Some((overlay_bounds, mouse_interaction)) - } else { - None }; - if let Some((overlay_bounds, overlay_interaction)) = overlay { - let base_cursor = if overlay_bounds.contains(cursor_position) { + if let Some(layer) = &self.overlay { + let base_cursor = if layer.layout.bounds().contains(cursor_position) + { Point::new(-1.0, -1.0) } else { cursor_position @@ -389,8 +369,6 @@ where base_cursor, &viewport, ); - - overlay_interaction } else { self.root.widget.draw( renderer, @@ -399,13 +377,55 @@ where cursor_position, &viewport, ); + }; - self.root.widget.mouse_interaction( - Layout::new(&self.base.layout), - &viewport, - cursor_position, - ) - } + let base_interaction = self.root.widget.mouse_interaction( + Layout::new(&self.base.layout), + &viewport, + cursor_position, + ); + + let Self { + overlay, + root, + base, + .. + } = self; + + // TODO: Currently, we need to call Widget::overlay twice to + // implement the painter's algorithm properly. + // + // Once we have a proper persistent widget tree, we should be able to + // avoid this additional call. + overlay + .as_ref() + .and_then(|layer| { + root.overlay(Layout::new(&base.layout)).map(|overlay| { + let overlay_interaction = overlay.mouse_interaction( + Layout::new(&layer.layout), + &viewport, + cursor_position, + ); + + let overlay_bounds = layer.layout.bounds(); + + renderer.with_layer(viewport, |renderer| { + overlay.draw( + renderer, + &renderer::Style::default(), + Layout::new(&layer.layout), + cursor_position, + ); + }); + + if overlay_bounds.contains(cursor_position) { + overlay_interaction + } else { + base_interaction + } + }) + }) + .unwrap_or(base_interaction) } /// Relayouts and returns a new [`UserInterface`] using the provided |