use roost_ui::{Component, Context};
use roost_ui::events::OnEvent;
use roost_ui::drawable::{Color, Drawable, Image};
use crate::components::{Rectangle, AspectRatioImage};
use crate::components::button::GhostIconButton;
use crate::components::interface::general::InterfaceTrait;
use crate::components::interface::navigation::{AppPage, RootInfo, NavigatorEvent, NavigatorSelectable};
use roost_ui::layouts::{Bin, Column, Offset, Opt, Padding, Row, Size, Stack};
use crate::plugin::PelicanUI;
#[derive(Component, Debug)]
pub struct WebInterface(Column, Option<Opt<Box<dyn Drawable>>>, Option<Box<dyn AppPage>>, Option<WebFooter>);
impl OnEvent for WebInterface {}
impl InterfaceTrait for WebInterface {
fn app_page(&mut self) -> &mut Option<Box<dyn AppPage>> {&mut self.2}
fn navigator(&mut self) -> &mut Option<Opt<Box<dyn Drawable>>> {&mut self.1}
}
impl WebInterface {
pub fn new(
ctx: &mut Context,
start_page: Box<dyn AppPage>,
navigation: Option<(Vec<RootInfo>, Option<Vec<RootInfo>>)>,
socials: Option<Vec<(&'static str, String)>>
) -> Self {
let navigator = navigation.map(|n| Opt::new(Box::new(WebNavigator::new(ctx, n)) as Box<dyn Drawable>, true));
let footer = socials.map(|s| WebFooter::new(ctx, s));
let layout = Column::new(0.0, Offset::Start, Size::Fill, Padding::default());
WebInterface(layout, navigator, Some(start_page), footer)
}
}
#[derive(Debug, Component)]
pub struct WebNavigator(Row, Image, Bin<Stack, Rectangle>, ButtonRow);
impl OnEvent for WebNavigator {}
impl WebNavigator {
pub fn new(
ctx: &mut Context,
mut navigation: (Vec<RootInfo>, Option<Vec<RootInfo>>),
) -> Self {
let mut buttons = Vec::new();
let group_id = uuid::Uuid::new_v4();
if let Some(n) = navigation.1 { navigation.0.extend(n); }
for (index, info) in navigation.0.into_iter().enumerate() {
let closure = move |ctx: &mut Context| ctx.trigger_event(NavigatorEvent(index));
buttons.push(NavigatorSelectable::desktop_icon(ctx, info.icon, &info.label, closure, 0 == index, group_id));
}
let wordmark = ctx.get::<PelicanUI>().get().0.theme().brand.wordmark.clone();
WebNavigator(
Row::new(32.0, Offset::Center, Size::Fit, Padding::new(48.0)),
AspectRatioImage::new(wordmark, (150.0, 35.0)),
Bin (
Stack(Offset::Center, Offset::Center, Size::Fill, Size::Static(5.0), Padding::default()),
Rectangle::new(Color::TRANSPARENT, 0.0, None)
),
ButtonRow::new(buttons)
)
}
}
#[derive(Debug, Component)]
struct ButtonRow(Row, Vec<NavigatorSelectable>);
impl OnEvent for ButtonRow {}
impl ButtonRow {
fn new(buttons: Vec<NavigatorSelectable>) -> Self {
ButtonRow(Row::center(8.0), buttons)
}
}
#[derive(Debug, Component)]
struct WebFooter(Row, Vec<GhostIconButton>);
impl OnEvent for WebFooter {}
impl WebFooter {
fn new(
ctx: &mut Context,
socials: Vec<(&'static str, String)>
) -> Self {
let buttons = socials.into_iter().map(|(i, _)| GhostIconButton::new(ctx, i, |_: &mut Context| {})).collect();
let layout = Row::new(8.0, Offset::Center, Size::Fit, Padding::new(48.0));
WebFooter(layout, buttons)
}
}