use crate::geometry::Size;
use crate::layout::{Cell, Extent, Inset, Placement};
use super::{CompositionLayout, Element, Slot};
pub struct Patch {
pub(super) id: Option<String>,
pub(super) placements: Vec<PatchPlacement>,
pub(super) aspect: Option<(f64, f64)>,
pub(super) margin: Inset,
pub(super) padding: Inset,
}
pub struct PatchPlacement {
pub placement: Placement,
pub region: String,
pub cell: Cell,
}
impl Patch {
pub fn new(id: impl Into<String>) -> Self {
Self {
id: Some(id.into()),
placements: Vec::new(),
aspect: None,
margin: Inset::default(),
padding: Inset::default(),
}
}
pub(super) fn anonymous() -> Self {
Self {
id: None,
placements: Vec::new(),
aspect: None,
margin: Inset::default(),
padding: Inset::default(),
}
}
pub fn slot(mut self, s: Slot, cell: Cell) -> Self {
let (r, c, rs, cs) = s.placement();
self.placements.push(PatchPlacement {
placement: Placement::at(r, c).span(rs, cs),
region: s.name().to_string(),
cell,
});
self
}
pub fn into_placements(self) -> Vec<PatchPlacement> {
self.placements
}
pub fn patch_id(&self) -> Option<&str> {
self.id.as_deref()
}
pub fn aspect_ratio(&self) -> Option<(f64, f64)> {
self.aspect
}
pub fn margin_inset(&self) -> &Inset {
&self.margin
}
pub fn padding_inset(&self) -> &Inset {
&self.padding
}
pub fn place_at(
mut self,
region: impl Into<String>,
row: u16,
col: u16,
span: Span,
cell: Cell,
) -> Self {
self.placements.push(PatchPlacement {
placement: Placement::at(row, col).span(span.rows, span.cols),
region: region.into(),
cell,
});
self
}
pub fn aspect(mut self, w: f64, h: f64) -> Self {
self.aspect = Some((w, h));
self
}
pub fn margin(mut self, inset: Inset) -> Self {
self.margin = inset;
self
}
pub fn margin_all(self, length: Extent) -> Self {
self.margin(Inset::all(length))
}
pub fn padding(mut self, inset: Inset) -> Self {
self.padding = inset;
self
}
pub fn padding_all(self, length: Extent) -> Self {
self.padding(Inset::all(length))
}
pub fn solve(self, size: Size, dpi: f64) -> CompositionLayout {
Element::Patch(self).solve(size, dpi)
}
}
#[derive(Clone, Copy, Debug)]
pub struct Span {
pub rows: u16,
pub cols: u16,
}
impl Span {
pub fn cell() -> Self {
Self { rows: 1, cols: 1 }
}
pub fn rows(r: u16) -> Self {
Self { rows: r, cols: 1 }
}
pub fn cols(c: u16) -> Self {
Self { rows: 1, cols: c }
}
pub fn rc(r: u16, c: u16) -> Self {
Self { rows: r, cols: c }
}
}