add popup_below_widget to show a popup area below another widget
Closes https://github.com/emilk/egui/issues/122
This commit is contained in:
parent
577aa2699f
commit
3bec7c4f68
4 changed files with 63 additions and 29 deletions
|
@ -9,6 +9,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
## Unreleased
|
||||
|
||||
### Added ⭐
|
||||
|
||||
* `egui::popup::popup_below_widget`: show a popup area below another widget
|
||||
|
||||
|
||||
## 0.8.0 - 2021-01-17 - Grid layout & new visual style
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ pub fn combo_box(
|
|||
selected: impl Into<String>,
|
||||
menu_contents: impl FnOnce(&mut Ui),
|
||||
) -> Response {
|
||||
const MAX_COMBO_HEIGHT: f32 = 128.0;
|
||||
|
||||
let popup_id = button_id.with("popup");
|
||||
|
||||
let button_active = ui.memory().is_popup_open(popup_id);
|
||||
|
@ -85,33 +83,14 @@ pub fn combo_box(
|
|||
ui.painter()
|
||||
.galley(text_rect.min, galley, text_style, visuals.text_color());
|
||||
});
|
||||
|
||||
if button_response.clicked {
|
||||
ui.memory().toggle_popup(popup_id);
|
||||
}
|
||||
|
||||
if ui.memory().is_popup_open(popup_id) {
|
||||
let parent_clip_rect = ui.clip_rect();
|
||||
|
||||
Area::new(popup_id)
|
||||
.order(Order::Foreground)
|
||||
.fixed_pos(button_response.rect.left_bottom())
|
||||
.show(ui.ctx(), |ui| {
|
||||
ui.set_clip_rect(parent_clip_rect); // for when the combo-box is in a scroll area.
|
||||
let frame = Frame::popup(ui.style());
|
||||
let frame_margin = frame.margin;
|
||||
frame.show(ui, |ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::left()), |ui| {
|
||||
ui.set_width(button_response.rect.width() - 2.0 * frame_margin.x);
|
||||
ScrollArea::from_max_height(MAX_COMBO_HEIGHT).show(ui, menu_contents);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if ui.input().key_pressed(Key::Escape) || ui.input().mouse.click && !button_response.clicked
|
||||
{
|
||||
ui.memory().close_popup();
|
||||
}
|
||||
}
|
||||
const MAX_COMBO_HEIGHT: f32 = 128.0;
|
||||
crate::popup::popup_below_widget(ui, popup_id, &button_response, |ui| {
|
||||
ScrollArea::from_max_height(MAX_COMBO_HEIGHT).show(ui, menu_contents)
|
||||
});
|
||||
|
||||
button_response
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ pub(crate) mod collapsing_header;
|
|||
mod combo_box;
|
||||
pub(crate) mod frame;
|
||||
pub(crate) mod panel;
|
||||
pub(crate) mod popup;
|
||||
pub mod popup;
|
||||
pub(crate) mod resize;
|
||||
pub(crate) mod scroll_area;
|
||||
pub(crate) mod window;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Show popup windows, tooltips, context menus etc.
|
||||
|
||||
use crate::*;
|
||||
|
||||
/// Show a tooltip at the current mouse position (if any).
|
||||
|
@ -33,7 +35,7 @@ pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
|
|||
|
||||
// TODO: default size
|
||||
let id = Id::tooltip();
|
||||
let response = show_popup(ctx, id, window_pos, add_contents);
|
||||
let response = show_tooltip_area(ctx, id, window_pos, add_contents);
|
||||
|
||||
let tooltip_rect = tooltip_rect.unwrap_or_else(Rect::nothing);
|
||||
ctx.frame_state().tooltip_rect = Some(tooltip_rect.union(response.rect));
|
||||
|
@ -58,7 +60,7 @@ pub fn show_tooltip_text(ctx: &CtxRef, text: impl Into<String>) {
|
|||
}
|
||||
|
||||
/// Show a pop-over window.
|
||||
fn show_popup(
|
||||
fn show_tooltip_area(
|
||||
ctx: &CtxRef,
|
||||
id: Id,
|
||||
window_pos: Pos2,
|
||||
|
@ -76,3 +78,52 @@ fn show_popup(
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Shows a popup below another widget.
|
||||
///
|
||||
/// Useful for drop-down menus (combo boxes) or suggestion menus under text fields.
|
||||
///
|
||||
/// You must open the popup with [`Memory::open_popup`] or [`Memory::toggle_popup`].
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// let response = ui.button("Open popup");
|
||||
/// let popup_id = ui.make_persistent_id("my_unique_id");
|
||||
/// if response.clicked {
|
||||
/// ui.memory().toggle_popup(popup_id);
|
||||
/// }
|
||||
/// egui::popup::popup_below_widget(ui, popup_id, &response, |ui| {
|
||||
/// ui.label("Some more info, or things you can select:");
|
||||
/// ui.label("…");
|
||||
/// });
|
||||
/// ```
|
||||
pub fn popup_below_widget(
|
||||
ui: &Ui,
|
||||
popup_id: Id,
|
||||
widget_response: &Response,
|
||||
add_contents: impl FnOnce(&mut Ui),
|
||||
) {
|
||||
if ui.memory().is_popup_open(popup_id) {
|
||||
let parent_clip_rect = ui.clip_rect();
|
||||
|
||||
Area::new(popup_id)
|
||||
.order(Order::Foreground)
|
||||
.fixed_pos(widget_response.rect.left_bottom())
|
||||
.show(ui.ctx(), |ui| {
|
||||
ui.set_clip_rect(parent_clip_rect); // for when the combo-box is in a scroll area.
|
||||
let frame = Frame::popup(ui.style());
|
||||
let frame_margin = frame.margin;
|
||||
frame.show(ui, |ui| {
|
||||
ui.with_layout(Layout::top_down_justified(Align::left()), |ui| {
|
||||
ui.set_width(widget_response.rect.width() - 2.0 * frame_margin.x);
|
||||
add_contents(ui)
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if ui.input().key_pressed(Key::Escape) || ui.input().mouse.click && !widget_response.clicked
|
||||
{
|
||||
ui.memory().close_popup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue