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:
@@ -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,
|
||||||
|
|||||||
@@ -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()));
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user