use egui::{CornerRadius, Frame, Margin, Popup, PopupCloseBehavior, Response, Stroke, Ui};
use crate::theme::Theme;
#[derive(Debug, Clone)]
#[must_use = "Call `.show(&target, |ui| ...)` to render the context menu."]
pub struct ContextMenu {
id_salt: egui::IdSalt,
min_width: f32,
}
impl ContextMenu {
pub fn new(id_salt: impl crate::IdSalt) -> Self {
Self {
id_salt: egui::IdSalt::new(("elegance::context_menu", id_salt)),
min_width: 200.0,
}
}
#[inline]
pub fn min_width(mut self, min_width: f32) -> Self {
self.min_width = min_width;
self
}
pub fn show<R>(self, target: &Response, add_contents: impl FnOnce(&mut Ui) -> R) -> Option<R> {
let theme = Theme::current(&target.ctx);
let p = &theme.palette;
let r = theme.card_radius as u8;
let frame = Frame::new()
.fill(p.card)
.stroke(Stroke::new(1.0, p.border))
.corner_radius(CornerRadius::same(r))
.inner_margin(Margin::same(4));
Popup::context_menu(target)
.id(target.id.with_salt(self.id_salt))
.frame(frame)
.close_behavior(PopupCloseBehavior::CloseOnClick)
.show(|ui| {
ui.set_min_width(self.min_width);
ui.spacing_mut().item_spacing.y = 2.0;
add_contents(ui)
})
.map(|r| r.inner)
}
}