Skip to main content

revue/widget/canvas/
widget.rs

1//! Canvas widget implementations
2
3use super::braille::{BrailleContext, BrailleGrid};
4use super::draw::DrawContext;
5use crate::widget::traits::{RenderContext, View};
6
7/// A canvas widget for custom drawing (character-based)
8pub struct Canvas<F>
9where
10    F: Fn(&mut DrawContext),
11{
12    draw_fn: F,
13}
14
15impl<F> Canvas<F>
16where
17    F: Fn(&mut DrawContext),
18{
19    /// Create a new canvas with a drawing function
20    pub fn new(draw_fn: F) -> Self {
21        Self { draw_fn }
22    }
23}
24
25impl<F> View for Canvas<F>
26where
27    F: Fn(&mut DrawContext),
28{
29    fn render(&self, ctx: &mut RenderContext) {
30        let mut draw_ctx = DrawContext::new(ctx.buffer, ctx.area);
31        (self.draw_fn)(&mut draw_ctx);
32    }
33}
34
35/// Create a canvas with a drawing function
36pub fn canvas<F>(draw_fn: F) -> Canvas<F>
37where
38    F: Fn(&mut DrawContext),
39{
40    Canvas::new(draw_fn)
41}
42
43/// A high-resolution canvas using braille patterns
44///
45/// Each terminal cell represents a 2x4 dot matrix, providing
46/// 2x horizontal and 4x vertical resolution.
47///
48/// # Example
49///
50/// ```rust,ignore
51/// use revue::prelude::*;
52///
53/// let chart = BrailleCanvas::new(|ctx| {
54///     // Draw a sine wave
55///     let points: Vec<(f64, f64)> = (0..ctx.width())
56///         .map(|x| {
57///             let y = (x as f64 * 0.1).sin() * 10.0 + 20.0;
58///             (x as f64, y)
59///         })
60///         .collect();
61///     ctx.points(points, Color::CYAN);
62///
63///     // Draw a circle
64///     ctx.circle(40.0, 20.0, 15.0, Color::YELLOW);
65/// });
66/// ```
67pub struct BrailleCanvas<F>
68where
69    F: Fn(&mut BrailleContext),
70{
71    draw_fn: F,
72}
73
74impl<F> BrailleCanvas<F>
75where
76    F: Fn(&mut BrailleContext),
77{
78    /// Create a new braille canvas with a drawing function
79    pub fn new(draw_fn: F) -> Self {
80        Self { draw_fn }
81    }
82}
83
84impl<F> View for BrailleCanvas<F>
85where
86    F: Fn(&mut BrailleContext),
87{
88    fn render(&self, ctx: &mut RenderContext) {
89        let mut grid = BrailleGrid::new(ctx.area.width, ctx.area.height);
90        let mut braille_ctx = BrailleContext::new(&mut grid);
91        (self.draw_fn)(&mut braille_ctx);
92        grid.render(ctx.buffer, ctx.area);
93    }
94}
95
96/// Create a braille canvas with a drawing function
97pub fn braille_canvas<F>(draw_fn: F) -> BrailleCanvas<F>
98where
99    F: Fn(&mut BrailleContext),
100{
101    BrailleCanvas::new(draw_fn)
102}