1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00

Allow opening multiple popups

This commit is contained in:
Lucas Meurer
2025-03-03 17:03:48 +01:00
parent 40bf21728d
commit 34b5b211b3
3 changed files with 20 additions and 15 deletions

View File

@@ -519,7 +519,7 @@ impl<'a> Popup<'a> {
_ => mem.open_popup(id), _ => mem.open_popup(id),
} }
} else { } else {
mem.close_popup(); mem.close_popup(id);
} }
} }
Some(SetOpenCommand::Toggle) => { Some(SetOpenCommand::Toggle) => {
@@ -599,7 +599,7 @@ impl<'a> Popup<'a> {
} }
OpenKind::Memory { .. } => { OpenKind::Memory { .. } => {
if should_close { if should_close {
ctx.memory_mut(|mem| mem.close_popup()); ctx.memory_mut(|mem| mem.close_popup(id));
} }
} }
} }

View File

@@ -94,7 +94,7 @@ pub struct Memory {
/// If position is [`None`], the popup position will be calculated based on some configuration /// If position is [`None`], the popup position will be calculated based on some configuration
/// (e.g. relative to some other widget). /// (e.g. relative to some other widget).
#[cfg_attr(feature = "persistence", serde(skip))] #[cfg_attr(feature = "persistence", serde(skip))]
popup: Option<(Id, Option<Pos2>)>, popup: Vec<(Id, Option<Pos2>)>,
#[cfg_attr(feature = "persistence", serde(skip))] #[cfg_attr(feature = "persistence", serde(skip))]
everything_is_visible: bool, everything_is_visible: bool,
@@ -1070,37 +1070,42 @@ impl Memory {
/// ## Popups /// ## Popups
/// Popups are things like combo-boxes, color pickers, menus etc. /// Popups are things like combo-boxes, color pickers, menus etc.
/// Only one can be open at a time.
impl Memory { impl Memory {
/// Is the given popup open? /// Is the given popup open?
pub fn is_popup_open(&self, popup_id: Id) -> bool { pub fn is_popup_open(&self, popup_id: Id) -> bool {
self.popup.is_some_and(|(id, _)| id == popup_id) || self.everything_is_visible() self.popup.iter().any(|(id, _)| id == &popup_id) || self.everything_is_visible()
} }
/// Is any popup open? /// Is any popup open?
pub fn any_popup_open(&self) -> bool { pub fn any_popup_open(&self) -> bool {
self.popup.is_some() || self.everything_is_visible() !self.popup.is_empty() || self.everything_is_visible()
} }
/// Open the given popup and close all others. /// Open the given popup.
pub fn open_popup(&mut self, popup_id: Id) { pub fn open_popup(&mut self, popup_id: Id) {
self.popup = Some((popup_id, None)); self.popup.push((popup_id, None));
} }
/// Open the popup and remember its position. /// Open the popup and remember its position.
pub fn open_popup_at(&mut self, popup_id: Id, pos: impl Into<Option<Pos2>>) { pub fn open_popup_at(&mut self, popup_id: Id, pos: impl Into<Option<Pos2>>) {
self.popup = Some((popup_id, pos.into())); self.popup.push((popup_id, pos.into()));
} }
/// Get the position for this popup. /// Get the position for this popup.
pub fn popup_position(&self, id: Id) -> Option<Pos2> { pub fn popup_position(&self, id: Id) -> Option<Pos2> {
self.popup self.popup
.and_then(|(popup_id, pos)| if popup_id == id { pos } else { None }) .iter()
.find_map(|(popup_id, pos)| if *popup_id == id { *pos } else { None })
} }
/// Close the open popup, if any. /// Close the popup with the given id.
pub fn close_popup(&mut self) { pub fn close_popup(&mut self, id: Id) {
self.popup = None; self.popup.retain(|(popup_id, _)| *popup_id != id);
}
/// Close all popups.
pub fn close_all_popups(&mut self) {
self.popup.clear();
} }
/// Toggle the given popup between closed and open. /// Toggle the given popup between closed and open.
@@ -1108,7 +1113,7 @@ impl Memory {
/// Note: At most, only one popup can be open at a time. /// Note: At most, only one popup can be open at a time.
pub fn toggle_popup(&mut self, popup_id: Id) { pub fn toggle_popup(&mut self, popup_id: Id) {
if self.is_popup_open(popup_id) { if self.is_popup_open(popup_id) {
self.close_popup(); self.close_popup(popup_id);
} else { } else {
self.open_popup(popup_id); self.open_popup(popup_id);
} }

View File

@@ -521,7 +521,7 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
if !button_response.clicked() if !button_response.clicked()
&& (ui.input(|i| i.key_pressed(Key::Escape)) || area_response.clicked_elsewhere()) && (ui.input(|i| i.key_pressed(Key::Escape)) || area_response.clicked_elsewhere())
{ {
ui.memory_mut(|mem| mem.close_popup()); ui.memory_mut(|mem| mem.close_popup(popup_id));
} }
} }