fyodor/drawable/
extended_impl.rs

1use crossterm::style::ContentStyle;
2use unicode_width::UnicodeWidthChar;
3
4use crate::{
5    canvas::CanvasLike,
6    cell::Cell,
7    layout::{Dims, Pos},
8};
9
10use super::Drawable;
11
12impl<D> Drawable for &D
13where
14    D: Drawable,
15{
16    type X = D::X;
17    type Y = D::Y;
18
19    fn draw(&self, pos: impl Into<Pos<Self::X, Self::Y>>, frame: &mut impl CanvasLike) {
20        (*self).draw(pos, frame);
21    }
22}
23
24impl Drawable for (ContentStyle, &&str) {
25    type X = i32;
26    type Y = i32;
27
28    fn draw(&self, pos: impl Into<Dims>, frame: &mut impl CanvasLike) {
29        let pos = pos.into();
30
31        let mut i = 0;
32        let (style, string) = self;
33        for chr in string.chars() {
34            (*style, &chr).draw((pos.x + i as i32, pos.y), frame);
35            i += chr.width().unwrap_or(0) as i32;
36        }
37    }
38}
39
40impl Drawable for (ContentStyle, &char) {
41    type X = i32;
42    type Y = i32;
43
44    fn draw(&self, pos: impl Into<Dims>, frame: &mut impl CanvasLike) {
45        let Pos { x, y } = pos.into();
46        let (style, chr) = *self;
47
48        if x >= frame.size().x || y >= frame.size().y {
49            return;
50        }
51
52        let width = chr.width().unwrap_or(0) as i32;
53        if width == 0 {
54            return;
55        }
56
57        let cell = Cell::styled(*chr, style);
58
59        frame.setd((x, y), cell);
60
61        for i in x + 1..x + width {
62            frame.setd((i, y), Cell::PlaceHolder);
63        }
64    }
65}
66
67impl Drawable for (ContentStyle, &String) {
68    type X = i32;
69    type Y = i32;
70
71    fn draw(&self, pos: impl Into<Dims>, frame: &mut impl CanvasLike) {
72        (self.0, &self.1.as_str()).draw(pos, frame);
73    }
74}