chargrid_menu 0.3.1

chargrid menus
Documentation
use crate::{MenuIndexFromScreenCoord, MenuInstanceChoose};
use chargrid_event_routine::{
    event_or_peek_with_handled, DataSelector, EventOrPeek, EventRoutine, Handled, ViewSelector,
};
use chargrid_input::Input;
use chargrid_render::{ColModify, Frame, View, ViewContext};

pub trait ChooseSelector: DataSelector {
    type ChooseOutput: MenuInstanceChoose;
    fn choose_mut<'a>(&self, input: &'a mut Self::DataInput) -> &'a mut Self::ChooseOutput;
}

pub struct MenuInstanceRoutine<S> {
    s: S,
}
impl<S> MenuInstanceRoutine<S>
where
    S: DataSelector + ViewSelector + ChooseSelector,
    S::ViewOutput: MenuIndexFromScreenCoord,
    for<'a> S::ViewOutput: View<&'a S::DataOutput>,
{
    pub fn new(s: S) -> Self {
        Self { s }
    }
}

impl<S> EventRoutine for MenuInstanceRoutine<S>
where
    S: ViewSelector + ChooseSelector,
    S::ViewOutput: MenuIndexFromScreenCoord,
    for<'a> S::ViewOutput: View<&'a S::DataOutput>,
{
    type Return = <S::ChooseOutput as MenuInstanceChoose>::Output;
    type Data = S::DataInput;
    type View = S::ViewInput;
    type Event = Input;

    fn handle<EP>(
        self,
        data: &mut Self::Data,
        view: &Self::View,
        event_or_peek: EP,
    ) -> Handled<Self::Return, Self>
    where
        EP: EventOrPeek<Event = Self::Event>,
    {
        event_or_peek_with_handled(event_or_peek, self, |s, event| {
            let choose = s.s.choose_mut(data);
            let menu_view = s.s.view(view);
            if let Some(menu_output) = choose.choose(menu_view, event) {
                Handled::Return(menu_output)
            } else {
                Handled::Continue(s)
            }
        })
    }

    fn view<F, C>(
        &self,
        data: &Self::Data,
        view: &mut Self::View,
        context: ViewContext<C>,
        frame: &mut F,
    ) where
        F: Frame,
        C: ColModify,
    {
        let view = self.s.view_mut(view);
        let data = self.s.data(data);
        view.view(data, context, frame)
    }
}