ori_core/views/
painter.rsuse ori_macro::Build;
use crate::{
canvas::{Curve, FillRule, Paint},
context::{BuildCx, DrawCx, EventCx, LayoutCx, RebuildCx},
event::Event,
layout::{Size, Space},
rebuild::Rebuild,
view::View,
};
pub fn painter<T>(draw: impl FnMut(&mut DrawCx, &mut T) + 'static) -> Painter<T> {
Painter::new(draw)
}
pub fn circle<T>(radius: f32, paint: impl Into<Paint>) -> Painter<T> {
Painter::new({
let paint = paint.into();
move |cx, _| {
cx.fill(
Curve::circle(cx.rect().center(), radius),
FillRule::NonZero,
paint.clone(),
);
}
})
.size(Size::all(radius * 2.0))
}
pub fn ellipse<T>(size: Size, paint: impl Into<Paint>) -> Painter<T> {
Painter::new({
let paint = paint.into();
move |cx, _| {
cx.fill(Curve::ellipse(cx.rect()), FillRule::NonZero, paint.clone());
}
})
.size(size)
}
pub fn rect<T>(size: Size, paint: impl Into<Paint>) -> Painter<T> {
Painter::new({
let paint = paint.into();
move |cx, _| {
cx.fill(Curve::rect(cx.rect()), FillRule::NonZero, paint.clone());
}
})
.size(size)
}
#[derive(Build, Rebuild)]
pub struct Painter<T> {
#[allow(clippy::type_complexity)]
pub draw: Box<dyn FnMut(&mut DrawCx, &mut T)>,
pub size: Option<Size>,
}
impl<T> Painter<T> {
pub fn new(draw: impl FnMut(&mut DrawCx, &mut T) + 'static) -> Self {
Self {
draw: Box::new(draw),
size: None,
}
}
}
impl<T> View<T> for Painter<T> {
type State = ();
fn build(&mut self, _cx: &mut BuildCx, _data: &mut T) -> Self::State {}
fn rebuild(&mut self, _state: &mut Self::State, cx: &mut RebuildCx, _data: &mut T, old: &Self) {
Rebuild::rebuild(self, cx, old);
}
fn event(
&mut self,
_state: &mut Self::State,
_cx: &mut EventCx,
_data: &mut T,
_event: &Event,
) -> bool {
false
}
fn layout(
&mut self,
_state: &mut Self::State,
_cx: &mut LayoutCx,
_data: &mut T,
space: Space,
) -> Size {
match self.size {
Some(size) => space.fit(size),
None => space.max,
}
}
fn draw(&mut self, _state: &mut Self::State, cx: &mut DrawCx, data: &mut T) {
(self.draw)(cx, data);
}
}