use crate::atoms::ListItem;
use egui::Ui;
use egui_cha::ViewCtx;
pub struct Menu<'a> {
items: &'a [&'a str],
compact: bool,
}
impl<'a> Menu<'a> {
pub fn new(items: &'a [&'a str]) -> Self {
Self {
items,
compact: false,
}
}
pub fn compact(mut self) -> Self {
self.compact = true;
self
}
pub fn show_with<Msg>(
self,
ctx: &mut ViewCtx<'_, Msg>,
active: usize,
on_change: impl Fn(usize) -> Msg,
) {
if let Some(new_idx) = self.render(ctx.ui, active) {
ctx.emit(on_change(new_idx));
}
}
pub fn show(self, ui: &mut Ui, active: &mut usize) {
if let Some(new_idx) = self.render(ui, *active) {
*active = new_idx;
}
}
fn render(self, ui: &mut Ui, active: usize) -> Option<usize> {
let mut clicked_idx: Option<usize> = None;
let compact = self.compact;
ui.vertical(|ui| {
ui.spacing_mut().item_spacing.y = 0.0; for (i, item) in self.items.iter().enumerate() {
let is_active = i == active;
let mut list_item = ListItem::new(*item).selected(is_active);
if compact {
list_item = list_item.compact();
}
let response = list_item.show(ui);
if response.clicked() && !is_active {
clicked_idx = Some(i);
}
}
});
clicked_idx
}
}
pub struct IconMenu<'a> {
items: &'a [(&'a str, &'static str)], compact: bool,
}
impl<'a> IconMenu<'a> {
pub fn new(items: &'a [(&'a str, &'static str)]) -> Self {
Self {
items,
compact: false,
}
}
pub fn compact(mut self) -> Self {
self.compact = true;
self
}
pub fn show_with<Msg>(
self,
ctx: &mut ViewCtx<'_, Msg>,
active: usize,
on_change: impl Fn(usize) -> Msg,
) {
if let Some(new_idx) = self.render(ctx.ui, active) {
ctx.emit(on_change(new_idx));
}
}
pub fn show(self, ui: &mut Ui, active: &mut usize) {
if let Some(new_idx) = self.render(ui, *active) {
*active = new_idx;
}
}
fn render(self, ui: &mut Ui, active: usize) -> Option<usize> {
let mut clicked_idx: Option<usize> = None;
let compact = self.compact;
ui.vertical(|ui| {
ui.spacing_mut().item_spacing.y = 0.0; for (i, (label, icon)) in self.items.iter().enumerate() {
let is_active = i == active;
let mut list_item = ListItem::new(*label).icon(*icon).selected(is_active);
if compact {
list_item = list_item.compact();
}
let response = list_item.show(ui);
if response.clicked() && !is_active {
clicked_idx = Some(i);
}
}
});
clicked_idx
}
}