use crate::{
AnyElement, App, Bounds, ClickEvent, ElementSize, InteractiveElement, IntoElement,
ParentElement, Pixels, Sizable, Stateful, Styled as _, Window, canvas,
};
#[derive(Default)]
struct ChildElementOptions {
ix: usize,
size: ElementSize,
}
pub trait ChildElement: Sizable + IntoElement {
fn with_ix(self, ix: usize) -> Self;
}
pub struct AnyChildElement(Box<dyn FnOnce(ChildElementOptions) -> AnyElement>);
impl AnyChildElement {
pub fn new(element: impl ChildElement + 'static) -> Self {
Self(Box::new(|options| {
element
.with_ix(options.ix)
.with_size(options.size)
.into_any_element()
}))
}
pub fn into_any(self, ix: usize, size: ElementSize) -> AnyElement {
(self.0)(ChildElementOptions { ix, size })
}
}
pub trait ElementExt: ParentElement + Sized {
fn on_prepaint<F>(self, f: F) -> Self
where
F: FnOnce(Bounds<Pixels>, &mut Window, &mut App) + 'static,
{
self.child(
canvas(
move |bounds, window, cx| f(bounds, window, cx),
|_, _, _, _| {},
)
.absolute()
.size_full(),
)
}
}
impl<T: ParentElement> ElementExt for T {}
pub trait InteractiveElementExt: InteractiveElement {
fn on_double_click(
mut self,
listener: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
) -> Self
where
Self: Sized,
{
self.interactivity().on_click(move |event, window, cx| {
if event.click_count() == 2 {
listener(event, window, cx);
}
});
self
}
}
impl<E: InteractiveElement> InteractiveElementExt for Stateful<E> {}