101 lines
2.7 KiB
Rust
101 lines
2.7 KiB
Rust
use crate::{
|
|
layout::{IdFnTag, Ui, UiModule, Widget, WidgetId, WidgetIdFn, WidgetLike},
|
|
util::Id,
|
|
};
|
|
|
|
pub trait UiCtx {
|
|
fn ui(&mut self) -> &mut Ui
|
|
where
|
|
Self: Sized;
|
|
}
|
|
|
|
pub trait Event<Ctx>: Sized {
|
|
type Module: UiModule + EventModule<Ctx, Self> + Default;
|
|
type Data;
|
|
}
|
|
|
|
pub trait EventModule<Ctx, E: Event<Ctx>> {
|
|
fn register(&mut self, id: Id, event: E, f: impl EventFn<Ctx, E::Data>);
|
|
}
|
|
|
|
pub trait EventFn<Ctx, Data>: FnMut(&mut Ctx, Data) + 'static {}
|
|
impl<F: FnMut(&mut Ctx, Data) + 'static, Ctx, Data> EventFn<Ctx, Data> for F {}
|
|
|
|
pub trait Eventable<W, Ctx, Tag> {
|
|
fn on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
f: impl EventFn<Ctx, E::Data>,
|
|
) -> impl WidgetIdFn<W> + Eventable<W, Ctx, IdFnTag>;
|
|
|
|
fn id_on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
f: impl FnMut(&WidgetId<W>, &mut Ctx, E::Data) + 'static,
|
|
) -> impl WidgetIdFn<W> + Eventable<W, Ctx, IdFnTag>
|
|
where
|
|
W: Widget;
|
|
|
|
fn edit_on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
f: impl FnMut(&mut W, E::Data) + 'static,
|
|
) -> impl WidgetIdFn<W> + Eventable<W, Ctx, IdFnTag>
|
|
where
|
|
W: Widget,
|
|
Ctx: UiCtx;
|
|
}
|
|
|
|
pub trait Ctxable<W, Tag> {
|
|
/// sets context which lets event functions work without needing to specify generics
|
|
fn ctx<Ctx>(self) -> impl WidgetLike<Tag> + Eventable<W, Ctx, Tag>;
|
|
}
|
|
|
|
impl<W: WidgetLike<Tag>, Tag> Ctxable<W::Widget, Tag> for W {
|
|
fn ctx<Ctx>(self) -> impl WidgetLike<Tag> + Eventable<W::Widget, Ctx, Tag> {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<W: WidgetLike<Tag>, Ctx, Tag> Eventable<W::Widget, Ctx, Tag> for W {
|
|
fn on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
f: impl EventFn<Ctx, E::Data>,
|
|
) -> impl WidgetIdFn<W::Widget> + Eventable<W::Widget, Ctx, IdFnTag> {
|
|
move |ui| {
|
|
let id = self.add(ui);
|
|
ui.modules
|
|
.get_mut::<E::Module>()
|
|
.register(id.id.duplicate(), event, f);
|
|
id
|
|
}
|
|
}
|
|
|
|
fn id_on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
mut f: impl FnMut(&WidgetId<W::Widget>, &mut Ctx, E::Data) + 'static,
|
|
) -> impl WidgetIdFn<W::Widget> + Eventable<W::Widget, Ctx, IdFnTag>
|
|
where
|
|
W::Widget: Widget,
|
|
{
|
|
self.with_id(move |ui, id| {
|
|
let id2 = id.clone();
|
|
id.on(event, move |ctx, pos| f(&id2, ctx, pos)).add(ui)
|
|
})
|
|
}
|
|
|
|
fn edit_on<E: Event<Ctx>>(
|
|
self,
|
|
event: E,
|
|
mut f: impl FnMut(&mut W::Widget, E::Data) + 'static,
|
|
) -> impl WidgetIdFn<W::Widget> + Eventable<W::Widget, Ctx, IdFnTag>
|
|
where
|
|
W::Widget: Widget,
|
|
Ctx: UiCtx,
|
|
{
|
|
self.id_on(event, move |id, ctx, pos| f(&mut ctx.ui()[id], pos))
|
|
}
|
|
}
|