From 1bd45c35ebcea5ab37f4c188c2162049c15f8b9c Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Wed, 14 Oct 2020 15:26:31 +0200 Subject: [PATCH] Collapsing header returns header and body responses --- TODO.md | 1 + egui/src/containers/collapsing_header.rs | 68 ++++++++++++++++++------ egui/src/containers/mod.rs | 4 +- egui/src/demos/demo_window.rs | 1 + egui/src/ui.rs | 2 +- 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/TODO.md b/TODO.md index 38defad0..8d93f84e 100644 --- a/TODO.md +++ b/TODO.md @@ -139,6 +139,7 @@ TODO-list for the Egui project. If you looking for something to do, look here. * [ ] Rename things to be more consistent with Dear ImGui ? * [ ] Put everything in `Context` behind the same Mutex? `struct Context(Arc>);`, with e.g. `context.lock().memory.foo`? +* [ ] Resolve the various uses of "heading", "header", "title" etc ## Global widget search diff --git a/egui/src/containers/collapsing_header.rs b/egui/src/containers/collapsing_header.rs index af8ea915..978d1706 100644 --- a/egui/src/containers/collapsing_header.rs +++ b/egui/src/containers/collapsing_header.rs @@ -163,6 +163,7 @@ impl CollapsingHeader { struct Prepared { id: Id, + header_response: Response, state: State, } @@ -197,25 +198,28 @@ impl CollapsingHeader { desired_size = desired_size.at_least(ui.style().spacing.interact_size); let rect = ui.allocate_space(desired_size); - let response = ui.interact(rect, id, Sense::click()); - let text_pos = pos2(text_pos.x, response.rect.center().y - galley.size.y / 2.0); + let header_response = ui.interact(rect, id, Sense::click()); + let text_pos = pos2( + text_pos.x, + header_response.rect.center().y - galley.size.y / 2.0, + ); let mut state = State::from_memory_with_default_open(ui.ctx(), id, default_open); - if response.clicked { + if header_response.clicked { state.toggle(ui); } let bg_index = ui.painter().add(PaintCmd::Noop); { - let (mut icon_rect, _) = ui.style().spacing.icon_rectangles(response.rect); + let (mut icon_rect, _) = ui.style().spacing.icon_rectangles(header_response.rect); icon_rect.set_center(pos2( - response.rect.left() + ui.style().spacing.indent / 2.0, - response.rect.center().y, + header_response.rect.left() + ui.style().spacing.indent / 2.0, + header_response.rect.center().y, )); let icon_response = Response { rect: icon_rect, - ..response.clone() + ..header_response.clone() }; let openness = state.openness(ui.ctx(), id); paint_icon(ui, openness, &icon_response); @@ -226,27 +230,59 @@ impl CollapsingHeader { text_pos, galley, label.text_style_or_default(ui.style()), - ui.style().interact(&response).text_color(), + ui.style().interact(&header_response).text_color(), ); painter.set( bg_index, PaintCmd::Rect { - rect: response.rect, - corner_radius: ui.style().interact(&response).corner_radius, - fill: ui.style().interact(&response).bg_fill, + rect: header_response.rect, + corner_radius: ui.style().interact(&header_response).corner_radius, + fill: ui.style().interact(&header_response).bg_fill, stroke: Default::default(), }, ); - Prepared { id, state } + Prepared { + id, + header_response, + state, + } } - pub fn show(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Option { - let Prepared { id, mut state } = self.begin(ui); + pub fn show( + self, + ui: &mut Ui, + add_contents: impl FnOnce(&mut Ui) -> R, + ) -> CollapsingResponse { + let Prepared { + id, + header_response, + mut state, + } = self.begin(ui); let ret_response = state.add_contents(ui, id, |ui| ui.indent(id, add_contents).0); - let ret = ret_response.map(|ri| ri.0); ui.memory().collapsing_headers.insert(id, state); - ret + + if let Some((ret, response)) = ret_response { + CollapsingResponse { + header_response, + body_response: Some(response), + body_returned: Some(ret), + } + } else { + CollapsingResponse { + header_response, + body_response: None, + body_returned: None, + } + } } } + +pub struct CollapsingResponse { + pub header_response: Response, + /// None iff collapsed. + pub body_response: Option, + /// None iff collapsed. + pub body_returned: Option, +} diff --git a/egui/src/containers/mod.rs b/egui/src/containers/mod.rs index 244997b8..b636292d 100644 --- a/egui/src/containers/mod.rs +++ b/egui/src/containers/mod.rs @@ -12,6 +12,6 @@ pub(crate) mod scroll_area; pub(crate) mod window; pub use { - area::Area, collapsing_header::CollapsingHeader, combo_box::*, frame::Frame, popup::*, - resize::Resize, scroll_area::ScrollArea, window::Window, + area::Area, collapsing_header::*, combo_box::*, frame::Frame, popup::*, resize::Resize, + scroll_area::ScrollArea, window::Window, }; diff --git a/egui/src/demos/demo_window.rs b/egui/src/demos/demo_window.rs index 28cd6922..35ad9c9b 100644 --- a/egui/src/demos/demo_window.rs +++ b/egui/src/demos/demo_window.rs @@ -451,6 +451,7 @@ impl Tree { CollapsingHeader::new(name) .default_open(depth < 1) .show(ui, |ui| self.children_ui(ui, depth)) + .body_returned .unwrap_or(Action::Keep) } diff --git a/egui/src/ui.rs b/egui/src/ui.rs index 9c238b83..7bbb5f67 100644 --- a/egui/src/ui.rs +++ b/egui/src/ui.rs @@ -637,7 +637,7 @@ impl Ui { &mut self, heading: impl Into, add_contents: impl FnOnce(&mut Ui) -> R, - ) -> Option { + ) -> CollapsingResponse { CollapsingHeader::new(heading).show(self, add_contents) }