mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Add a PopupStyle, so the theme frames popups and menus
A `Popup` framed itself with `Frame::popup` and left item spacing to the ambient style. Both now come from a `PopupStyle`, which is what lets a theme give a menu its own padding and its own item rhythm. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +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 _, MENU_CLASS},
|
widget_style::{Classes, HasClasses as _, MENU_CLASS, PopupStyle},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// What should we anchor the popup to?
|
/// What should we anchor the popup to?
|
||||||
@@ -594,8 +594,10 @@ 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 classes = Classes::default().with_class_if(MENU_CLASS, kind == PopupKind::Menu);
|
||||||
|
|
||||||
let mut area = Area::new(id)
|
let mut area = Area::new(id)
|
||||||
.with_class_if(MENU_CLASS, kind == PopupKind::Menu)
|
.with_classes(classes.clone())
|
||||||
.order(kind.order())
|
.order(kind.order())
|
||||||
.pivot(pivot)
|
.pivot(pivot)
|
||||||
.fixed_pos(anchor)
|
.fixed_pos(anchor)
|
||||||
@@ -618,7 +620,12 @@ impl<'a> Popup<'a> {
|
|||||||
|
|
||||||
let mut response = area.show(&ctx, |ui| {
|
let mut response = area.show(&ctx, |ui| {
|
||||||
style.apply(ui.style_mut());
|
style.apply(ui.style_mut());
|
||||||
let frame = frame.unwrap_or_else(|| Frame::popup(ui.style()));
|
|
||||||
|
// The theme decides how the popup is framed and how tightly its items sit together.
|
||||||
|
let popup_style: PopupStyle = ui.widget_style(id, &classes);
|
||||||
|
ui.spacing_mut().item_spacing = popup_style.item_spacing;
|
||||||
|
|
||||||
|
let frame = frame.unwrap_or(popup_style.frame);
|
||||||
frame.show(ui, content).inner
|
frame.show(ui, content).inner
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use crate::{
|
|||||||
theme::StyleProvider,
|
theme::StyleProvider,
|
||||||
widget_style::{
|
widget_style::{
|
||||||
BaseStyle, ButtonStyle, CheckboxStyle, HasClasses as _, LabelStyle, LayoutStyle,
|
BaseStyle, ButtonStyle, CheckboxStyle, HasClasses as _, LabelStyle, LayoutStyle,
|
||||||
READ_ONLY_CLASS, SELECTED_CLASS, SeparatorStyle, StyleArgs, TextEditStyle, TextVisuals,
|
PopupStyle, READ_ONLY_CLASS, SELECTED_CLASS, SeparatorStyle, StyleArgs, TextEditStyle,
|
||||||
WidgetState,
|
TextVisuals, WidgetState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,6 +99,17 @@ impl StyleProvider<ButtonStyle> for DefaultStyle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StyleProvider<PopupStyle> for DefaultStyle {
|
||||||
|
fn style(&mut self, modifiers: &StyleArgs<'_>) -> PopupStyle {
|
||||||
|
let StyleArgs { style, .. } = modifiers;
|
||||||
|
|
||||||
|
PopupStyle {
|
||||||
|
frame: Frame::popup(style),
|
||||||
|
item_spacing: style.spacing.item_spacing,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StyleProvider<TextEditStyle> for DefaultStyle {
|
impl StyleProvider<TextEditStyle> for DefaultStyle {
|
||||||
fn style(&mut self, modifiers: &StyleArgs<'_>) -> TextEditStyle {
|
fn style(&mut self, modifiers: &StyleArgs<'_>) -> TextEditStyle {
|
||||||
let StyleArgs {
|
let StyleArgs {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ use crate::{
|
|||||||
theme::{StyleProvider, default_style::DefaultStyle},
|
theme::{StyleProvider, default_style::DefaultStyle},
|
||||||
util::IdTypeMap,
|
util::IdTypeMap,
|
||||||
widget_style::{
|
widget_style::{
|
||||||
BaseStyle, ButtonStyle, CheckboxStyle, LabelStyle, SeparatorStyle, TextEditStyle,
|
BaseStyle, ButtonStyle, CheckboxStyle, LabelStyle, PopupStyle, SeparatorStyle,
|
||||||
WidgetStyle,
|
TextEditStyle, WidgetStyle,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,6 +52,11 @@ impl Default for Themes {
|
|||||||
Arc::new(Mutex::new(Box::new(DefaultStyle))),
|
Arc::new(Mutex::new(Box::new(DefaultStyle))),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
themes.insert_temp::<ThemeWrap<PopupStyle>>(
|
||||||
|
Id::NULL,
|
||||||
|
Arc::new(Mutex::new(Box::new(DefaultStyle))),
|
||||||
|
);
|
||||||
|
|
||||||
themes.insert_temp::<ThemeWrap<TextEditStyle>>(
|
themes.insert_temp::<ThemeWrap<TextEditStyle>>(
|
||||||
Id::NULL,
|
Id::NULL,
|
||||||
Arc::new(Mutex::new(Box::new(DefaultStyle))),
|
Arc::new(Mutex::new(Box::new(DefaultStyle))),
|
||||||
|
|||||||
@@ -98,6 +98,21 @@ pub struct ButtonStyle {
|
|||||||
|
|
||||||
impl WidgetStyle for ButtonStyle {}
|
impl WidgetStyle for ButtonStyle {}
|
||||||
|
|
||||||
|
/// Dedicated style for a [`crate::Popup`], including menus and tooltips
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct PopupStyle {
|
||||||
|
/// Frame around the popup's contents, including its padding.
|
||||||
|
pub frame: Frame,
|
||||||
|
|
||||||
|
/// Spacing between the items inside the popup.
|
||||||
|
///
|
||||||
|
/// A menu wants its items flush against each other, while a tooltip wants them spaced out
|
||||||
|
/// like any other content.
|
||||||
|
pub item_spacing: Vec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WidgetStyle for PopupStyle {}
|
||||||
|
|
||||||
/// Dedicated text edit style
|
/// Dedicated text edit style
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct TextEditStyle {
|
pub struct TextEditStyle {
|
||||||
|
|||||||
Reference in New Issue
Block a user