use std::fmt::Debug;
use iced::{
Alignment::Center,
Element,
widget::{button, column, container, row, text},
};
use snora_core::{Menu, MenuAction};
use crate::icon::icon_element;
use crate::style::menu_button_style;
pub(crate) struct MenuGeometry {
pub(crate) gap: f32,
}
impl MenuGeometry {
pub(crate) const fn unstyled() -> Self {
Self { gap: 6.0 }
}
}
pub fn render_menu<'a, Message, MenuId, MenuItemId, F>(
menu: Menu<MenuId, MenuItemId>,
on_action: &'a F,
is_active: bool,
) -> Element<'a, Message>
where
Message: Clone + 'a,
MenuId: Clone + Debug + PartialEq + 'a,
MenuItemId: Clone + Debug + 'a,
F: Fn(MenuAction<MenuId, MenuItemId>) -> Message + 'a,
{
build_menu(menu, on_action, is_active, MenuGeometry::unstyled())
}
pub(crate) fn build_menu<'a, Message, MenuId, MenuItemId, F>(
menu: Menu<MenuId, MenuItemId>,
on_action: &'a F,
is_active: bool,
geometry: MenuGeometry,
) -> Element<'a, Message>
where
Message: Clone + 'a,
MenuId: Clone + Debug + PartialEq + 'a,
MenuItemId: Clone + Debug + 'a,
F: Fn(MenuAction<MenuId, MenuItemId>) -> Message + 'a,
{
let mut header_content = row![].spacing(geometry.gap).align_y(Center);
if let Some(ref ic) = menu.icon {
header_content = header_content.push(icon_element(ic));
}
header_content = header_content.push(text(menu.label).size(14));
let trigger_msg = on_action(MenuAction::MenuPressed(menu.id.clone()));
let mut stack = column![];
stack = stack.push(
button(header_content)
.style(menu_button_style)
.on_press(trigger_msg),
);
if !is_active {
return container(stack).into();
}
for item in menu.items {
let mut btn_content = row![].spacing(geometry.gap).align_y(Center);
if let Some(ref ic) = item.icon {
btn_content = btn_content.push(icon_element(ic));
}
btn_content = btn_content.push(text(item.label).size(14));
let msg = on_action(MenuAction::MenuItemPressed {
menu_id: item.menu_id.clone(),
menu_item_id: item.id.clone(),
});
stack = stack.push(button(btn_content).style(menu_button_style).on_press(msg));
}
container(stack).into()
}