1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 23:00:04 -04:00

Better popup api

This commit is contained in:
lucasmerlin
2026-02-20 23:46:28 +01:00
parent 66df116fa0
commit 63360ae527
3 changed files with 55 additions and 38 deletions

View File

@@ -1,4 +1,4 @@
use emath::{Align2, Rect, Vec2}; use emath::{Align2, Vec2};
use crate::{ use crate::{
Area, Color32, Context, Frame, Id, InnerResponse, Order, Response, Sense, Ui, UiKind, Area, Color32, Context, Frame, Id, InnerResponse, Order, Response, Sense, Ui, UiKind,

View File

@@ -185,8 +185,9 @@ pub struct Popup<'a> {
layout: Layout, layout: Layout,
frame: Option<Frame>, frame: Option<Frame>,
style: StyleModifier, style: StyleModifier,
/// `None` = use style default, `Some(None)` = no backdrop, `Some(Some(color))` = this color /// `None` = use style default, `Some(bool)` = explicit override
backdrop_color: Option<Option<Color32>>, backdrop: Option<bool>,
backdrop_color: Option<Color32>,
} }
impl<'a> Popup<'a> { impl<'a> Popup<'a> {
@@ -209,6 +210,7 @@ impl<'a> Popup<'a> {
layout: Layout::default(), layout: Layout::default(),
frame: None, frame: None,
style: StyleModifier::default(), style: StyleModifier::default(),
backdrop: None,
backdrop_color: None, backdrop_color: None,
} }
} }
@@ -416,15 +418,23 @@ impl<'a> Popup<'a> {
/// Show a backdrop behind the popup. /// Show a backdrop behind the popup.
/// ///
/// The backdrop covers the entire screen, blocking interaction with the rest of the UI. /// The backdrop covers the entire screen, blocking interaction with the rest of the UI.
/// The color is determined by [`crate::Visuals::popup_backdrop_color`].
/// ///
/// - `None` — no backdrop is shown. /// By default, this is controlled by [`crate::Visuals::popup_backdrop`].
/// - `Some(color)` — show a backdrop with this color.
/// - `Some(Color32::PLACEHOLDER)` — use the default from [`crate::Visuals::popup_backdrop_color`].
///
/// By default, this is controlled by [`crate::Visuals::popup_backdrop_color`].
/// Calling this method overrides the global style for this popup. /// Calling this method overrides the global style for this popup.
///
/// Note: submenus never show a backdrop, even if this is set to `true`.
#[inline] #[inline]
pub fn backdrop(mut self, color: Option<Color32>) -> Self { pub fn backdrop(mut self, show: bool) -> Self {
self.backdrop = Some(show);
self
}
/// Override the backdrop color for this popup.
///
/// By default, the color comes from [`crate::Visuals::popup_backdrop_color`].
#[inline]
pub fn backdrop_color(mut self, color: Color32) -> Self {
self.backdrop_color = Some(color); self.backdrop_color = Some(color);
self self
} }
@@ -572,6 +582,7 @@ impl<'a> Popup<'a> {
layout, layout,
frame, frame,
style, style,
backdrop,
backdrop_color, backdrop_color,
} = self; } = self;
@@ -608,25 +619,22 @@ impl<'a> Popup<'a> {
area = area.default_width(width); area = area.default_width(width);
} }
// Resolve backdrop color: per-instance override, or fall back to global style // Resolve whether to show a backdrop:
let resolved_backdrop = match backdrop_color { // - Explicit per-instance override takes priority
Some(explicit) => explicit, // - Otherwise, fall back to global style
None => ctx.global_style().visuals.popup_backdrop_color, // - Submenus (parent layer is Foreground) never show a backdrop
}; let is_submenu = layer_id.order == Order::Foreground;
let resolved_backdrop = match resolved_backdrop { let show_backdrop = !is_submenu
Some(color) if color == Color32::PLACEHOLDER => { && backdrop.unwrap_or_else(|| ctx.global_style().visuals.popup_backdrop);
ctx.global_style().visuals.popup_backdrop_color
}
other => other,
};
let mut backdrop_clicked = false; let mut backdrop_clicked = false;
let mut response = area.show(&ctx, |ui| { let mut response = area.show(&ctx, |ui| {
backdrop_clicked = if let Some(color) = resolved_backdrop { if show_backdrop {
super::modal::paint_backdrop(ui, color) && was_open_last_frame let color = backdrop_color
} else { .unwrap_or_else(|| ctx.global_style().visuals.popup_backdrop_color);
false backdrop_clicked =
}; super::modal::paint_backdrop(ui, color) && was_open_last_frame;
}
style.apply(ui.style_mut()); style.apply(ui.style_mut());
let frame = frame.unwrap_or_else(|| Frame::popup(ui.style())); let frame = frame.unwrap_or_else(|| Frame::popup(ui.style()));

View File

@@ -1029,14 +1029,20 @@ pub struct Visuals {
/// Default is `Color32::from_black_alpha(100)`. /// Default is `Color32::from_black_alpha(100)`.
pub modal_backdrop_color: Color32, pub modal_backdrop_color: Color32,
/// The default backdrop color for popups. /// The backdrop color for popups.
/// ///
/// If `Some`, popups show a backdrop by default. /// Only used when [`Self::popup_backdrop`] is `true` or when a popup
/// If `None` (default), popups don't show a backdrop unless explicitly enabled /// explicitly enables the backdrop via [`crate::Popup::backdrop`].
/// via [`crate::Popup::backdrop`]. ///
/// Default is `Color32::from_black_alpha(100)`.
pub popup_backdrop_color: Color32,
/// Whether popups show a backdrop by default.
/// ///
/// Individual popups can still override this with [`crate::Popup::backdrop`]. /// Individual popups can still override this with [`crate::Popup::backdrop`].
pub popup_backdrop_color: Option<Color32>, ///
/// Default is `false`.
pub popup_backdrop: bool,
pub resize_corner_size: f32, pub resize_corner_size: f32,
@@ -1475,7 +1481,8 @@ impl Visuals {
}, },
modal_backdrop_color: Color32::from_black_alpha(100), modal_backdrop_color: Color32::from_black_alpha(100),
popup_backdrop_color: None, popup_backdrop_color: Color32::from_black_alpha(100),
popup_backdrop: false,
resize_corner_size: 12.0, resize_corner_size: 12.0,
@@ -2171,6 +2178,7 @@ impl Visuals {
popup_shadow, popup_shadow,
modal_backdrop_color, modal_backdrop_color,
popup_backdrop_color, popup_backdrop_color,
popup_backdrop,
resize_corner_size, resize_corner_size,
@@ -2353,16 +2361,17 @@ impl Visuals {
ui.add(popup_shadow); ui.add(popup_shadow);
ui.end_row(); ui.end_row();
ui.label("Modal backdrop"); ui.label("Modal backdrop color");
ui.color_edit_button_srgba(modal_backdrop_color); ui.color_edit_button_srgba(modal_backdrop_color);
ui.end_row(); ui.end_row();
ui_optional_color( ui.label("Popup backdrop color");
ui, ui.color_edit_button_srgba(popup_backdrop_color);
popup_backdrop_color, ui.end_row();
Color32::from_black_alpha(100),
"Popup backdrop", ui.label("Popup backdrop");
); ui.checkbox(popup_backdrop, "");
ui.end_row();
}); });
}); });