mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 22:30:03 -04:00
Add support for calling ui.close() within animating panel
This commit is contained in:
@@ -223,13 +223,14 @@ impl SidePanel {
|
|||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
self.show_inside_dyn(ui, Box::new(add_contents))
|
self.show_inside_dyn(ui, false, Box::new(add_contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show the panel inside a [`Ui`].
|
/// Show the panel inside a [`Ui`].
|
||||||
fn show_inside_dyn<'c, R>(
|
fn show_inside_dyn<'c, R>(
|
||||||
self,
|
self,
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
|
closable: bool,
|
||||||
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
let Self {
|
let Self {
|
||||||
@@ -257,6 +258,7 @@ impl SidePanel {
|
|||||||
let resize_id = id.with("__resize");
|
let resize_id = id.with("__resize");
|
||||||
let mut resize_hover = false;
|
let mut resize_hover = false;
|
||||||
let mut is_resizing = false;
|
let mut is_resizing = false;
|
||||||
|
let mut drag_to_close = false;
|
||||||
if resizable {
|
if resizable {
|
||||||
// First we read the resize interaction results, to avoid frame latency in the resize:
|
// First we read the resize interaction results, to avoid frame latency in the resize:
|
||||||
if let Some(resize_response) = ui.ctx().read_response(resize_id) {
|
if let Some(resize_response) = ui.ctx().read_response(resize_id) {
|
||||||
@@ -265,9 +267,15 @@ impl SidePanel {
|
|||||||
|
|
||||||
if is_resizing {
|
if is_resizing {
|
||||||
if let Some(pointer) = resize_response.interact_pointer_pos() {
|
if let Some(pointer) = resize_response.interact_pointer_pos() {
|
||||||
|
let old_width = width;
|
||||||
|
|
||||||
width = (pointer.x - side.side_x(panel_rect)).abs();
|
width = (pointer.x - side.side_x(panel_rect)).abs();
|
||||||
width = clamp_to_range(width, width_range).at_most(available_rect.width());
|
width = clamp_to_range(width, width_range).at_most(available_rect.width());
|
||||||
side.set_rect_width(&mut panel_rect, width);
|
side.set_rect_width(&mut panel_rect, width);
|
||||||
|
|
||||||
|
if closable && width <= width_range.min && width < old_width {
|
||||||
|
drag_to_close = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,13 +291,14 @@ impl SidePanel {
|
|||||||
Side::Right => UiKind::RightPanel,
|
Side::Right => UiKind::RightPanel,
|
||||||
}))
|
}))
|
||||||
.max_rect(panel_rect)
|
.max_rect(panel_rect)
|
||||||
.layout(Layout::top_down(Align::Min)),
|
.layout(Layout::top_down(Align::Min))
|
||||||
|
.with_closable(closable),
|
||||||
);
|
);
|
||||||
panel_ui.expand_to_include_rect(panel_rect);
|
panel_ui.expand_to_include_rect(panel_rect);
|
||||||
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
||||||
|
|
||||||
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
|
let frame = frame.unwrap_or_else(|| Frame::side_top_panel(ui.style()));
|
||||||
let inner_response = frame.show(&mut panel_ui, |ui| {
|
let mut inner_response = frame.show(&mut panel_ui, |ui| {
|
||||||
ui.set_min_height(ui.max_rect().height()); // Make sure the frame fills the full height
|
ui.set_min_height(ui.max_rect().height()); // Make sure the frame fills the full height
|
||||||
ui.set_min_width((width_range.min - frame.inner_margin.sum().x).at_least(0.0));
|
ui.set_min_width((width_range.min - frame.inner_margin.sum().x).at_least(0.0));
|
||||||
add_contents(ui)
|
add_contents(ui)
|
||||||
@@ -361,6 +370,10 @@ impl SidePanel {
|
|||||||
ui.painter().vline(resize_x, panel_rect.y_range(), stroke);
|
ui.painter().vline(resize_x, panel_rect.y_range(), stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if panel_ui.should_close() || drag_to_close {
|
||||||
|
inner_response.response.set_close();
|
||||||
|
}
|
||||||
|
|
||||||
inner_response
|
inner_response
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,13 +383,14 @@ impl SidePanel {
|
|||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
self.show_dyn(ctx, Box::new(add_contents))
|
self.show_dyn(ctx, false, Box::new(add_contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show the panel at the top level.
|
/// Show the panel at the top level.
|
||||||
fn show_dyn<'c, R>(
|
fn show_dyn<'c, R>(
|
||||||
self,
|
self,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
|
closable: bool,
|
||||||
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
let side = self.side;
|
let side = self.side;
|
||||||
@@ -390,7 +404,7 @@ impl SidePanel {
|
|||||||
);
|
);
|
||||||
panel_ui.set_clip_rect(ctx.screen_rect());
|
panel_ui.set_clip_rect(ctx.screen_rect());
|
||||||
|
|
||||||
let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
|
let inner_response = self.show_inside_dyn(&mut panel_ui, closable, add_contents);
|
||||||
let rect = inner_response.response.rect;
|
let rect = inner_response.response.rect;
|
||||||
|
|
||||||
match side {
|
match side {
|
||||||
@@ -433,7 +447,8 @@ impl SidePanel {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
// Show the real panel:
|
// Show the real panel:
|
||||||
Some(self.show(ctx, add_contents))
|
let closable = true;
|
||||||
|
Some(self.show_dyn(ctx, closable, Box::new(add_contents)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +481,8 @@ impl SidePanel {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
// Show the real panel:
|
// Show the real panel:
|
||||||
Some(self.show_inside(ui, add_contents))
|
let closable = true;
|
||||||
|
Some(self.show_inside_dyn(ui, closable, Box::new(add_contents)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,13 +729,14 @@ impl TopBottomPanel {
|
|||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
self.show_inside_dyn(ui, Box::new(add_contents))
|
self.show_inside_dyn(ui, false, Box::new(add_contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show the panel inside a [`Ui`].
|
/// Show the panel inside a [`Ui`].
|
||||||
fn show_inside_dyn<'c, R>(
|
fn show_inside_dyn<'c, R>(
|
||||||
self,
|
self,
|
||||||
ui: &mut Ui,
|
ui: &mut Ui,
|
||||||
|
closable: bool,
|
||||||
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
let Self {
|
let Self {
|
||||||
@@ -753,6 +770,7 @@ impl TopBottomPanel {
|
|||||||
let resize_id = id.with("__resize");
|
let resize_id = id.with("__resize");
|
||||||
let mut resize_hover = false;
|
let mut resize_hover = false;
|
||||||
let mut is_resizing = false;
|
let mut is_resizing = false;
|
||||||
|
let mut drag_to_close = false;
|
||||||
if resizable {
|
if resizable {
|
||||||
// First we read the resize interaction results, to avoid frame latency in the resize:
|
// First we read the resize interaction results, to avoid frame latency in the resize:
|
||||||
if let Some(resize_response) = ui.ctx().read_response(resize_id) {
|
if let Some(resize_response) = ui.ctx().read_response(resize_id) {
|
||||||
@@ -761,10 +779,16 @@ impl TopBottomPanel {
|
|||||||
|
|
||||||
if is_resizing {
|
if is_resizing {
|
||||||
if let Some(pointer) = resize_response.interact_pointer_pos() {
|
if let Some(pointer) = resize_response.interact_pointer_pos() {
|
||||||
|
let old_height = height;
|
||||||
|
|
||||||
height = (pointer.y - side.side_y(panel_rect)).abs();
|
height = (pointer.y - side.side_y(panel_rect)).abs();
|
||||||
height =
|
height =
|
||||||
clamp_to_range(height, height_range).at_most(available_rect.height());
|
clamp_to_range(height, height_range).at_most(available_rect.height());
|
||||||
side.set_rect_height(&mut panel_rect, height);
|
side.set_rect_height(&mut panel_rect, height);
|
||||||
|
|
||||||
|
if closable && height <= height_range.min && height < old_height {
|
||||||
|
drag_to_close = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -780,12 +804,13 @@ impl TopBottomPanel {
|
|||||||
TopBottomSide::Bottom => UiKind::BottomPanel,
|
TopBottomSide::Bottom => UiKind::BottomPanel,
|
||||||
}))
|
}))
|
||||||
.max_rect(panel_rect)
|
.max_rect(panel_rect)
|
||||||
.layout(Layout::top_down(Align::Min)),
|
.layout(Layout::top_down(Align::Min))
|
||||||
|
.with_closable(closable),
|
||||||
);
|
);
|
||||||
panel_ui.expand_to_include_rect(panel_rect);
|
panel_ui.expand_to_include_rect(panel_rect);
|
||||||
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
panel_ui.set_clip_rect(panel_rect); // If we overflow, don't do so visibly (#4475)
|
||||||
|
|
||||||
let inner_response = frame.show(&mut panel_ui, |ui| {
|
let mut inner_response = frame.show(&mut panel_ui, |ui| {
|
||||||
ui.set_min_width(ui.max_rect().width()); // Make the frame fill full width
|
ui.set_min_width(ui.max_rect().width()); // Make the frame fill full width
|
||||||
ui.set_min_height((height_range.min - frame.inner_margin.sum().y).at_least(0.0));
|
ui.set_min_height((height_range.min - frame.inner_margin.sum().y).at_least(0.0));
|
||||||
add_contents(ui)
|
add_contents(ui)
|
||||||
@@ -858,6 +883,10 @@ impl TopBottomPanel {
|
|||||||
ui.painter().hline(panel_rect.x_range(), resize_y, stroke);
|
ui.painter().hline(panel_rect.x_range(), resize_y, stroke);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if panel_ui.should_close() || drag_to_close {
|
||||||
|
inner_response.response.set_close();
|
||||||
|
}
|
||||||
|
|
||||||
inner_response
|
inner_response
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,13 +896,14 @@ impl TopBottomPanel {
|
|||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
self.show_dyn(ctx, Box::new(add_contents))
|
self.show_dyn(ctx, false, Box::new(add_contents))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show the panel at the top level.
|
/// Show the panel at the top level.
|
||||||
fn show_dyn<'c, R>(
|
fn show_dyn<'c, R>(
|
||||||
self,
|
self,
|
||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
|
closable: bool,
|
||||||
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
add_contents: Box<dyn FnOnce(&mut Ui) -> R + 'c>,
|
||||||
) -> InnerResponse<R> {
|
) -> InnerResponse<R> {
|
||||||
let available_rect = ctx.available_rect();
|
let available_rect = ctx.available_rect();
|
||||||
@@ -888,7 +918,7 @@ impl TopBottomPanel {
|
|||||||
);
|
);
|
||||||
panel_ui.set_clip_rect(ctx.screen_rect());
|
panel_ui.set_clip_rect(ctx.screen_rect());
|
||||||
|
|
||||||
let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
|
let inner_response = self.show_inside_dyn(&mut panel_ui, closable, add_contents);
|
||||||
let rect = inner_response.response.rect;
|
let rect = inner_response.response.rect;
|
||||||
|
|
||||||
match side {
|
match side {
|
||||||
@@ -973,7 +1003,8 @@ impl TopBottomPanel {
|
|||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
// Show the real panel:
|
// Show the real panel:
|
||||||
Some(self.show_inside(ui, add_contents))
|
let closable = true;
|
||||||
|
Some(self.show_inside_dyn(ui, closable, Box::new(add_contents)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user