mod layout;
mod node;
mod reconcile;
pub(crate) use self::layout::measure_canvas;
pub(crate) use self::node::CanvasNode;
pub(crate) use self::reconcile::{CanvasReconcile, reconcile_canvas};
use crate::core::element::{Element, ElementKind};
use crate::layout::hash::LayoutHash;
use crate::style::{Length, Rect, Style};
#[derive(Clone)]
pub struct CanvasItem {
pub rect: Rect,
pub element: Element,
}
impl CanvasItem {
pub fn new(rect: Rect, element: impl Into<Element>) -> Self {
Self {
rect,
element: element.into(),
}
}
}
impl std::borrow::Borrow<Element> for CanvasItem {
fn borrow(&self) -> &Element {
&self.element
}
}
#[derive(Clone)]
pub struct Canvas {
pub(crate) items: Vec<CanvasItem>,
pub(crate) style: Style,
pub(crate) passthrough: bool,
pub(crate) width: Length,
pub(crate) height: Length,
}
impl Default for Canvas {
fn default() -> Self {
Self {
items: Vec::new(),
style: Style::default(),
passthrough: false,
width: Length::Flex(1),
height: Length::Flex(1),
}
}
}
impl Canvas {
pub fn new() -> Self {
Self::default()
}
pub fn child_at(mut self, rect: Rect, child: impl Into<Element>) -> Self {
self.items.push(CanvasItem::new(rect, child));
self
}
pub fn items(mut self, items: impl IntoIterator<Item = CanvasItem>) -> Self {
self.items = items.into_iter().collect();
self
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn passthrough(mut self, passthrough: bool) -> Self {
self.passthrough = passthrough;
self
}
pub fn width(mut self, width: Length) -> Self {
self.width = width;
self
}
pub fn height(mut self, height: Length) -> Self {
self.height = height;
self
}
}
impl From<Canvas> for Element {
fn from(value: Canvas) -> Self {
Element::new(ElementKind::Canvas(value))
}
}
impl LayoutHash for Canvas {
fn layout_hash(
&self,
hasher: &mut impl std::hash::Hasher,
recurse: &dyn Fn(&Element) -> Option<u64>,
) -> Option<()> {
use std::hash::Hash;
self.passthrough.hash(hasher);
self.width.hash(hasher);
self.height.hash(hasher);
self.items.len().hash(hasher);
for item in &self.items {
item.rect.hash(hasher);
recurse(&item.element)?.hash(hasher);
}
Some(())
}
}