1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00

Let an Area carry classes, and mark menu popups with MENU_CLASS

This commit is contained in:
Lucas Meurer
2026-08-21 16:21:50 +02:00
parent 5b057a8d17
commit ce86533fa8
2 changed files with 25 additions and 0 deletions

View File

@@ -7,6 +7,7 @@ use emath::GuiRounding as _;
use crate::{ use crate::{
Align2, Context, Id, InnerResponse, LayerId, Layout, NumExt as _, Order, Pos2, Rect, Response, Align2, Context, Id, InnerResponse, LayerId, Layout, NumExt as _, Order, Pos2, Rect, Response,
Sense, Ui, UiBuilder, UiKind, UiStackInfo, Vec2, WidgetRect, WidgetWithState, emath, pos2, Sense, Ui, UiBuilder, UiKind, UiStackInfo, Vec2, WidgetRect, WidgetWithState, emath, pos2,
widget_style::{Classes, HasClasses},
}; };
/// State of an [`Area`] that is persisted between frames. /// State of an [`Area`] that is persisted between frames.
@@ -122,12 +123,23 @@ pub struct Area {
fade_in: bool, fade_in: bool,
layout: Layout, layout: Layout,
sizing_pass: bool, sizing_pass: bool,
classes: Classes,
} }
impl WidgetWithState for Area { impl WidgetWithState for Area {
type State = AreaState; type State = AreaState;
} }
impl HasClasses for Area {
fn classes(&self) -> &Classes {
&self.classes
}
fn classes_mut(&mut self) -> &mut Classes {
&mut self.classes
}
}
impl Area { impl Area {
/// The `id` must be globally unique. /// The `id` must be globally unique.
pub fn new(id: Id) -> Self { pub fn new(id: Id) -> Self {
@@ -149,6 +161,7 @@ impl Area {
fade_in: true, fade_in: true,
layout: Layout::default(), layout: Layout::default(),
sizing_pass: false, sizing_pass: false,
classes: Classes::default(),
} }
} }
@@ -400,6 +413,7 @@ pub(crate) struct Prepared {
fade_in: bool, fade_in: bool,
layout: Layout, layout: Layout,
classes: Classes,
} }
impl Area { impl Area {
@@ -434,6 +448,7 @@ impl Area {
fade_in, fade_in,
layout, layout,
sizing_pass: force_sizing_pass, sizing_pass: force_sizing_pass,
classes,
} = self; } = self;
let constrain_rect = constrain_rect.unwrap_or_else(|| ctx.content_rect()); let constrain_rect = constrain_rect.unwrap_or_else(|| ctx.content_rect());
@@ -581,6 +596,7 @@ impl Area {
sizing_pass, sizing_pass,
fade_in, fade_in,
layout, layout,
classes,
} }
} }
} }
@@ -612,6 +628,7 @@ impl Prepared {
let max_rect = self.state.rect(); let max_rect = self.state.rect();
let mut ui_builder = UiBuilder::new() let mut ui_builder = UiBuilder::new()
.with_classes(core::mem::take(&mut self.classes))
.ui_stack_info(self.info.take().unwrap_or_default()) .ui_stack_info(self.info.take().unwrap_or_default())
.layer_id(self.layer_id) .layer_id(self.layer_id)
.max_rect(max_rect) .max_rect(max_rect)

View File

@@ -7,6 +7,7 @@ use crate::{
Sense, Ui, UiKind, UiStackInfo, Sense, Ui, UiKind, UiStackInfo,
containers::menu::{MenuConfig, MenuState, menu_style}, containers::menu::{MenuConfig, MenuState, menu_style},
style::StyleModifier, style::StyleModifier,
widget_style::HasClasses as _,
}; };
/// What should we anchor the popup to? /// What should we anchor the popup to?
@@ -188,6 +189,12 @@ pub struct Popup<'a> {
} }
impl<'a> Popup<'a> { impl<'a> Popup<'a> {
/// Present on the [`crate::Ui`] of a menu popup, and so on every widget in it.
///
/// A menu lays its items out itself, so a widget in one is generally styled to fit that
/// layout rather than to stand on its own.
pub const CLASS_MENU: &'static str = "egui::popup::menu";
/// Create a new popup /// Create a new popup
pub fn new(id: Id, ctx: Context, anchor: impl Into<PopupAnchor>, layer_id: LayerId) -> Self { pub fn new(id: Id, ctx: Context, anchor: impl Into<PopupAnchor>, layer_id: LayerId) -> Self {
Self { Self {
@@ -594,6 +601,7 @@ impl<'a> Popup<'a> {
let (pivot, anchor) = best_align.pivot_pos(&anchor_rect, gap); let (pivot, anchor) = best_align.pivot_pos(&anchor_rect, gap);
let mut area = Area::new(id) let mut area = Area::new(id)
.with_class_if(Self::CLASS_MENU, kind == PopupKind::Menu)
.order(kind.order()) .order(kind.order())
.pivot(pivot) .pivot(pivot)
.fixed_pos(anchor) .fixed_pos(anchor)