use std::fmt::Debug;
use iced::{
Alignment::Center,
Element, Length, Padding,
widget::{container, space, text},
};
use snora_core::{LayoutDirection, Menu, MenuAction};
use crate::direction::row_dir;
use crate::menu::{MenuGeometry, build_menu};
use crate::style::chrome_container_style_with_radius;
#[derive(Debug, PartialEq)]
pub(crate) struct HeaderGeometry {
pub(crate) gap: f32,
pub(crate) pad_x: f32,
pub(crate) pad_y: f32,
pub(crate) radius: f32,
pub(crate) menu_gap: f32,
}
impl HeaderGeometry {
pub(crate) const fn unstyled() -> Self {
Self {
gap: 12.0,
pad_x: 16.0,
pad_y: 8.0,
radius: 0.0,
menu_gap: MenuGeometry::unstyled().gap,
}
}
}
pub fn app_header<'a, Message, MenuId, MenuItemId, F>(
title: &'a str,
menus: Vec<Menu<MenuId, MenuItemId>>,
on_menu_action: &'a F,
active_menu_id: Option<&MenuId>,
end_controls: Option<Element<'a, Message>>,
direction: LayoutDirection,
) -> Element<'a, Message>
where
Message: Clone + 'a,
MenuId: Clone + Debug + PartialEq + 'a,
MenuItemId: Clone + Debug + 'a,
F: Fn(MenuAction<MenuId, MenuItemId>) -> Message + 'a,
{
build_header(
title,
menus,
on_menu_action,
active_menu_id,
end_controls,
direction,
HeaderGeometry::unstyled(),
)
}
pub(crate) fn build_header<'a, Message, MenuId, MenuItemId, F>(
title: &'a str,
menus: Vec<Menu<MenuId, MenuItemId>>,
on_menu_action: &'a F,
active_menu_id: Option<&MenuId>,
end_controls: Option<Element<'a, Message>>,
direction: LayoutDirection,
geometry: HeaderGeometry,
) -> 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 start_group = iced::widget::row![
text(title)
.font(iced::Font {
weight: iced::font::Weight::Bold,
..Default::default()
})
.size(16),
container(space()).width(Length::Fixed(20.0)),
]
.align_y(Center)
.spacing(geometry.gap);
for menu in menus {
let is_active = active_menu_id == Some(&menu.id);
start_group = start_group.push(build_menu(
menu,
on_menu_action,
is_active,
MenuGeometry {
gap: geometry.menu_gap,
},
));
}
let filler = container(space()).width(Length::Fill);
let end_side: Element<'_, Message> = match end_controls {
Some(ctrls) => iced::widget::row![filler, ctrls]
.align_y(Center)
.spacing(geometry.gap)
.into(),
None => filler.into(),
};
let header_row = row_dir(direction, start_group, end_side).align_y(Center);
container(header_row)
.width(Length::Fill)
.padding(Padding::from([geometry.pad_y, geometry.pad_x]))
.style(move |theme| chrome_container_style_with_radius(theme, geometry.radius))
.into()
}