use crate::{shared::*, Font, ToFChar, screen::ZelData, modifiers::*};
pub struct Brush<'d, D: Drawable> {
pub(crate) drawable: Shared<'d, D>
}
impl<'d, D: Drawable> Clone for Brush<'d, D> {
fn clone(&self) -> Self {
Self { drawable: self.drawable.clone() }
}
}
impl <'a, D: Drawable> Brush<'a, D> {
pub fn affordance(&self) -> Affordance { self.drawable.borrow(|d| d.affordance()) }
pub fn get_font(&self) -> Font { self.drawable.borrow(|d| d.get_font()) }
pub fn bounds(&self) -> ZelRect { self.drawable.borrow(|x| x.bounds()) }
pub(crate) fn map<T: Drawable>(&self, builder: impl Fn(Shared<'a, D>) -> T ) -> Brush<'a, T> {
Brush {
drawable: Shared::owned(builder(self.drawable.clone()))
}
}
pub fn touch(&self, xy: impl ToZel, format: bool, modify: impl FnOnce(&mut ZelData)) {
let xy = xy.to_zel();
self.drawable.borrow(|d| d.raw_touch(xy, format, modify))
}
pub fn touch_i(&self, xy: (i32, i32), format: bool, modify: impl FnOnce(&mut ZelData)) {
self.touch(xy, format, modify)
}
pub fn at(&self, xy: impl ToZel) -> At<'a, D> {
At::new(xy.to_zel(), self.drawable.clone())
}
pub fn offset(&self, xy: impl ToZel) -> Brush<'a, Offset<'a, D>> {
let xy = xy.to_zel();
self.map(|x| Offset(xy, x))
}
pub fn clip(&self, xy0: impl ToZel, xy1: impl ToZel) -> Brush<'a, Clip<'a, D>> {
let xy0 = xy0.to_zel();
let xy1 = xy1.to_zel();
let rect = build_rect(xy0, xy1);
self.map(|x| Clip(rect, x))
}
pub fn font(&self, font: Font) -> Brush<'a, SetFont<'a, D>> {
self.map(|x| SetFont(font, x))
}
pub fn fg(&self, color: impl ToColor) -> Brush<'a, SetFg<'a, D>> {
let color = color.to_color();
self.map(|x| SetFg(color, x))
}
pub fn bg(&self, color: impl ToColor) -> Brush<'a, SetBg<'a, D>> {
let color = color.to_color();
self.map(|x| SetBg(color, x))
}
pub fn click(&self, affordance: Affordance) -> Brush<'a, SetClick<'a, D>> {
self.map(|x| SetClick(Some(affordance), x))
}
pub fn scroll(&self, affordance: Affordance) -> Brush<'a, SetScroll<'a, D>> {
self.map(|x| SetScroll(Some(affordance), x))
}
pub fn no_click(&self) -> Brush<'a, SetClick<'a, D>> {
self.map(|x| SetClick(None, x))
}
pub fn no_scroll(&self) -> Brush<'a, SetScroll<'a, D>> {
self.map(|x| SetScroll(None, x))
}
pub fn at_i(&self, xy: (i32, i32)) -> At<'a, D> {
self.at(xy)
}
pub fn offset_i(&self, xy: (i32, i32)) -> Brush<'a, Offset<'a, D>> {
self.offset(xy)
}
pub fn clip_i(&self, xy0: (i32, i32), xy1: (i32, i32)) -> Brush<'a, Clip<'a, D>> {
self.clip(xy0, xy1)
}
pub fn fill(&self, fc: impl ToFChar) {
let bounds = self.bounds();
self.at(bounds.min()).fill_rect(bounds.max(), fc);
}
pub fn clear(&self) {
self.fill(' ')
}
}