Collapsing header returns header and body responses
This commit is contained in:
parent
7561ccc189
commit
1bd45c35eb
5 changed files with 57 additions and 19 deletions
1
TODO.md
1
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 ?
|
* [ ] Rename things to be more consistent with Dear ImGui ?
|
||||||
* [ ] Put everything in `Context` behind the same Mutex? `struct Context(Arc<Mutex<ContextImpl>>);`, with e.g. `context.lock().memory.foo`?
|
* [ ] Put everything in `Context` behind the same Mutex? `struct Context(Arc<Mutex<ContextImpl>>);`, with e.g. `context.lock().memory.foo`?
|
||||||
|
* [ ] Resolve the various uses of "heading", "header", "title" etc
|
||||||
|
|
||||||
## Global widget search
|
## Global widget search
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ impl CollapsingHeader {
|
||||||
|
|
||||||
struct Prepared {
|
struct Prepared {
|
||||||
id: Id,
|
id: Id,
|
||||||
|
header_response: Response,
|
||||||
state: State,
|
state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,25 +198,28 @@ impl CollapsingHeader {
|
||||||
desired_size = desired_size.at_least(ui.style().spacing.interact_size);
|
desired_size = desired_size.at_least(ui.style().spacing.interact_size);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
|
|
||||||
let response = ui.interact(rect, id, Sense::click());
|
let header_response = ui.interact(rect, id, Sense::click());
|
||||||
let text_pos = pos2(text_pos.x, response.rect.center().y - galley.size.y / 2.0);
|
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);
|
let mut state = State::from_memory_with_default_open(ui.ctx(), id, default_open);
|
||||||
if response.clicked {
|
if header_response.clicked {
|
||||||
state.toggle(ui);
|
state.toggle(ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
let bg_index = ui.painter().add(PaintCmd::Noop);
|
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(
|
icon_rect.set_center(pos2(
|
||||||
response.rect.left() + ui.style().spacing.indent / 2.0,
|
header_response.rect.left() + ui.style().spacing.indent / 2.0,
|
||||||
response.rect.center().y,
|
header_response.rect.center().y,
|
||||||
));
|
));
|
||||||
let icon_response = Response {
|
let icon_response = Response {
|
||||||
rect: icon_rect,
|
rect: icon_rect,
|
||||||
..response.clone()
|
..header_response.clone()
|
||||||
};
|
};
|
||||||
let openness = state.openness(ui.ctx(), id);
|
let openness = state.openness(ui.ctx(), id);
|
||||||
paint_icon(ui, openness, &icon_response);
|
paint_icon(ui, openness, &icon_response);
|
||||||
|
@ -226,27 +230,59 @@ impl CollapsingHeader {
|
||||||
text_pos,
|
text_pos,
|
||||||
galley,
|
galley,
|
||||||
label.text_style_or_default(ui.style()),
|
label.text_style_or_default(ui.style()),
|
||||||
ui.style().interact(&response).text_color(),
|
ui.style().interact(&header_response).text_color(),
|
||||||
);
|
);
|
||||||
|
|
||||||
painter.set(
|
painter.set(
|
||||||
bg_index,
|
bg_index,
|
||||||
PaintCmd::Rect {
|
PaintCmd::Rect {
|
||||||
rect: response.rect,
|
rect: header_response.rect,
|
||||||
corner_radius: ui.style().interact(&response).corner_radius,
|
corner_radius: ui.style().interact(&header_response).corner_radius,
|
||||||
fill: ui.style().interact(&response).bg_fill,
|
fill: ui.style().interact(&header_response).bg_fill,
|
||||||
stroke: Default::default(),
|
stroke: Default::default(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Prepared { id, state }
|
Prepared {
|
||||||
|
id,
|
||||||
|
header_response,
|
||||||
|
state,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show<R>(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Option<R> {
|
pub fn show<R>(
|
||||||
let Prepared { id, mut state } = self.begin(ui);
|
self,
|
||||||
|
ui: &mut Ui,
|
||||||
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
|
) -> CollapsingResponse<R> {
|
||||||
|
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_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);
|
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<R> {
|
||||||
|
pub header_response: Response,
|
||||||
|
/// None iff collapsed.
|
||||||
|
pub body_response: Option<Response>,
|
||||||
|
/// None iff collapsed.
|
||||||
|
pub body_returned: Option<R>,
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@ pub(crate) mod scroll_area;
|
||||||
pub(crate) mod window;
|
pub(crate) mod window;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
area::Area, collapsing_header::CollapsingHeader, combo_box::*, frame::Frame, popup::*,
|
area::Area, collapsing_header::*, combo_box::*, frame::Frame, popup::*, resize::Resize,
|
||||||
resize::Resize, scroll_area::ScrollArea, window::Window,
|
scroll_area::ScrollArea, window::Window,
|
||||||
};
|
};
|
||||||
|
|
|
@ -451,6 +451,7 @@ impl Tree {
|
||||||
CollapsingHeader::new(name)
|
CollapsingHeader::new(name)
|
||||||
.default_open(depth < 1)
|
.default_open(depth < 1)
|
||||||
.show(ui, |ui| self.children_ui(ui, depth))
|
.show(ui, |ui| self.children_ui(ui, depth))
|
||||||
|
.body_returned
|
||||||
.unwrap_or(Action::Keep)
|
.unwrap_or(Action::Keep)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -637,7 +637,7 @@ impl Ui {
|
||||||
&mut self,
|
&mut self,
|
||||||
heading: impl Into<String>,
|
heading: impl Into<String>,
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
) -> Option<R> {
|
) -> CollapsingResponse<R> {
|
||||||
CollapsingHeader::new(heading).show(self, add_contents)
|
CollapsingHeader::new(heading).show(self, add_contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue