diff --git a/crates/egui/src/containers/modal.rs b/crates/egui/src/containers/modal.rs index cdd38f010..e84ac85ba 100644 --- a/crates/egui/src/containers/modal.rs +++ b/crates/egui/src/containers/modal.rs @@ -1,4 +1,4 @@ -use emath::{Align2, Rect, Vec2}; +use emath::{Align2, Vec2}; use crate::{ Area, Color32, Context, Frame, Id, InnerResponse, Order, Response, Sense, Ui, UiKind, diff --git a/crates/egui/src/containers/popup.rs b/crates/egui/src/containers/popup.rs index 6bdccaad2..cef01c397 100644 --- a/crates/egui/src/containers/popup.rs +++ b/crates/egui/src/containers/popup.rs @@ -185,8 +185,9 @@ pub struct Popup<'a> { layout: Layout, frame: Option, style: StyleModifier, - /// `None` = use style default, `Some(None)` = no backdrop, `Some(Some(color))` = this color - backdrop_color: Option>, + /// `None` = use style default, `Some(bool)` = explicit override + backdrop: Option, + backdrop_color: Option, } impl<'a> Popup<'a> { @@ -209,6 +210,7 @@ impl<'a> Popup<'a> { layout: Layout::default(), frame: None, style: StyleModifier::default(), + backdrop: None, backdrop_color: None, } } @@ -416,15 +418,23 @@ impl<'a> Popup<'a> { /// Show a backdrop behind the popup. /// /// 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. - /// - `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`]. + /// By default, this is controlled by [`crate::Visuals::popup_backdrop`]. /// Calling this method overrides the global style for this popup. + /// + /// Note: submenus never show a backdrop, even if this is set to `true`. #[inline] - pub fn backdrop(mut self, color: Option) -> 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 } @@ -572,6 +582,7 @@ impl<'a> Popup<'a> { layout, frame, style, + backdrop, backdrop_color, } = self; @@ -608,25 +619,22 @@ impl<'a> Popup<'a> { area = area.default_width(width); } - // Resolve backdrop color: per-instance override, or fall back to global style - let resolved_backdrop = match backdrop_color { - Some(explicit) => explicit, - None => ctx.global_style().visuals.popup_backdrop_color, - }; - let resolved_backdrop = match resolved_backdrop { - Some(color) if color == Color32::PLACEHOLDER => { - ctx.global_style().visuals.popup_backdrop_color - } - other => other, - }; + // Resolve whether to show a backdrop: + // - Explicit per-instance override takes priority + // - Otherwise, fall back to global style + // - Submenus (parent layer is Foreground) never show a backdrop + let is_submenu = layer_id.order == Order::Foreground; + let show_backdrop = !is_submenu + && backdrop.unwrap_or_else(|| ctx.global_style().visuals.popup_backdrop); let mut backdrop_clicked = false; let mut response = area.show(&ctx, |ui| { - backdrop_clicked = if let Some(color) = resolved_backdrop { - super::modal::paint_backdrop(ui, color) && was_open_last_frame - } else { - false - }; + if show_backdrop { + let color = backdrop_color + .unwrap_or_else(|| ctx.global_style().visuals.popup_backdrop_color); + backdrop_clicked = + super::modal::paint_backdrop(ui, color) && was_open_last_frame; + } style.apply(ui.style_mut()); let frame = frame.unwrap_or_else(|| Frame::popup(ui.style())); diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index 794d61601..27ce2516c 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -1029,14 +1029,20 @@ pub struct Visuals { /// Default is `Color32::from_black_alpha(100)`. pub modal_backdrop_color: Color32, - /// The default backdrop color for popups. + /// The backdrop color for popups. /// - /// If `Some`, popups show a backdrop by default. - /// If `None` (default), popups don't show a backdrop unless explicitly enabled - /// via [`crate::Popup::backdrop`]. + /// Only used when [`Self::popup_backdrop`] is `true` or when a popup + /// explicitly enables the 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`]. - pub popup_backdrop_color: Option, + /// + /// Default is `false`. + pub popup_backdrop: bool, pub resize_corner_size: f32, @@ -1475,7 +1481,8 @@ impl Visuals { }, 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, @@ -2171,6 +2178,7 @@ impl Visuals { popup_shadow, modal_backdrop_color, popup_backdrop_color, + popup_backdrop, resize_corner_size, @@ -2353,16 +2361,17 @@ impl Visuals { ui.add(popup_shadow); ui.end_row(); - ui.label("Modal backdrop"); + ui.label("Modal backdrop color"); ui.color_edit_button_srgba(modal_backdrop_color); ui.end_row(); - ui_optional_color( - ui, - popup_backdrop_color, - Color32::from_black_alpha(100), - "Popup backdrop", - ); + ui.label("Popup backdrop color"); + ui.color_edit_button_srgba(popup_backdrop_color); + ui.end_row(); + + ui.label("Popup backdrop"); + ui.checkbox(popup_backdrop, ""); + ui.end_row(); }); });