diff options
Diffstat (limited to 'native')
-rw-r--r-- | native/Cargo.toml | 2 | ||||
-rw-r--r-- | native/src/shell.rs | 5 | ||||
-rw-r--r-- | native/src/user_interface.rs | 71 | ||||
-rw-r--r-- | native/src/widget/pane_grid/title_bar.rs | 73 |
4 files changed, 103 insertions, 48 deletions
diff --git a/native/Cargo.toml b/native/Cargo.toml index a21385de..b4945c05 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iced_native" -version = "0.5.0" +version = "0.5.1" authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] edition = "2021" description = "A renderer-agnostic library for native GUIs" diff --git a/native/src/shell.rs b/native/src/shell.rs index 4a0aa9c6..b96d23e5 100644 --- a/native/src/shell.rs +++ b/native/src/shell.rs @@ -31,6 +31,11 @@ impl<'a, Message> Shell<'a, Message> { } } + /// Returns whether the current layout is invalid or not. + pub fn is_layout_invalid(&self) -> bool { + self.is_layout_invalid + } + /// Publish the given `Message` for an application to process it. pub fn publish(&mut self, message: Message) { self.messages.push(message); diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs index 26850f0a..d682a880 100644 --- a/native/src/user_interface.rs +++ b/native/src/user_interface.rs @@ -179,40 +179,61 @@ where clipboard: &mut dyn Clipboard, messages: &mut Vec<Message>, ) -> (State, Vec<event::Status>) { + use std::mem::ManuallyDrop; + let mut state = State::Updated; + let mut manual_overlay = ManuallyDrop::new( + self.root.overlay(Layout::new(&self.base), renderer), + ); - let (base_cursor, overlay_statuses) = if let Some(mut overlay) = - self.root.overlay(Layout::new(&self.base), renderer) - { + let (base_cursor, overlay_statuses) = if manual_overlay.is_some() { let bounds = self.bounds; + + let mut overlay = manual_overlay.as_mut().unwrap(); let mut layout = overlay.layout(renderer, bounds); + let mut event_statuses = Vec::new(); - let event_statuses = events - .iter() - .cloned() - .map(|event| { - let mut shell = Shell::new(messages); + for event in events.iter().cloned() { + let mut shell = Shell::new(messages); - let event_status = overlay.on_event( - event, - Layout::new(&layout), - cursor_position, - renderer, - clipboard, - &mut shell, + let event_status = overlay.on_event( + event, + Layout::new(&layout), + cursor_position, + renderer, + clipboard, + &mut shell, + ); + + event_statuses.push(event_status); + + if shell.is_layout_invalid() { + let _ = ManuallyDrop::into_inner(manual_overlay); + + self.base = renderer.layout( + &self.root, + &layout::Limits::new(Size::ZERO, self.bounds), ); + manual_overlay = ManuallyDrop::new( + self.root.overlay(Layout::new(&self.base), renderer), + ); + + if manual_overlay.is_none() { + break; + } + + overlay = manual_overlay.as_mut().unwrap(); + shell.revalidate_layout(|| { layout = overlay.layout(renderer, bounds); }); + } - if shell.are_widgets_invalid() { - state = State::Outdated; - } - - event_status - }) - .collect(); + if shell.are_widgets_invalid() { + state = State::Outdated; + } + } let base_cursor = if layout.bounds().contains(cursor_position) { // TODO: Type-safe cursor availability @@ -228,11 +249,17 @@ where (cursor_position, vec![event::Status::Ignored; events.len()]) }; + let _ = ManuallyDrop::into_inner(manual_overlay); + let event_statuses = events .iter() .cloned() .zip(overlay_statuses.into_iter()) .map(|(event, overlay_status)| { + if matches!(overlay_status, event::Status::Captured) { + return overlay_status; + } + let mut shell = Shell::new(messages); let event_status = self.root.widget.on_event( diff --git a/native/src/widget/pane_grid/title_bar.rs b/native/src/widget/pane_grid/title_bar.rs index 2a028dd5..14c3ab4e 100644 --- a/native/src/widget/pane_grid/title_bar.rs +++ b/native/src/widget/pane_grid/title_bar.rs @@ -114,20 +114,17 @@ where let mut children = padded.children(); let title_layout = children.next().unwrap(); - - self.content.draw( - renderer, - theme, - &inherited_style, - title_layout, - cursor_position, - viewport, - ); + let mut show_title = true; if let Some(controls) = &self.controls { let controls_layout = children.next().unwrap(); if show_controls || self.always_show_controls { + if title_layout.bounds().width + controls_layout.bounds().width + > padded.bounds().width + { + show_title = false; + } controls.draw( renderer, theme, @@ -138,6 +135,17 @@ where ); } } + + if show_title { + self.content.draw( + renderer, + theme, + &inherited_style, + title_layout, + cursor_position, + viewport, + ); + } } /// Returns whether the mouse cursor is over the pick area of the @@ -225,9 +233,15 @@ where let mut children = padded.children(); let title_layout = children.next().unwrap(); + let mut show_title = true; let control_status = if let Some(controls) = &mut self.controls { let controls_layout = children.next().unwrap(); + if title_layout.bounds().width + controls_layout.bounds().width + > padded.bounds().width + { + show_title = false; + } controls.on_event( event.clone(), @@ -241,14 +255,18 @@ where event::Status::Ignored }; - let title_status = self.content.on_event( - event, - title_layout, - cursor_position, - renderer, - clipboard, - shell, - ); + let title_status = if show_title { + self.content.on_event( + event, + title_layout, + cursor_position, + renderer, + clipboard, + shell, + ) + } else { + event::Status::Ignored + }; control_status.merge(title_status) } @@ -275,15 +293,20 @@ where if let Some(controls) = &self.controls { let controls_layout = children.next().unwrap(); + let controls_interaction = controls.mouse_interaction( + controls_layout, + cursor_position, + viewport, + renderer, + ); - controls - .mouse_interaction( - controls_layout, - cursor_position, - viewport, - renderer, - ) - .max(title_interaction) + if title_layout.bounds().width + controls_layout.bounds().width + > padded.bounds().width + { + controls_interaction + } else { + controls_interaction.max(title_interaction) + } } else { title_interaction } |