use ratatui::layout::Rect;
use ratatui::style::{Color, Modifier, Style};
use ratatui::symbols::Marker;
use ratatui::widgets::canvas::{Canvas, Context, Line};
use ratatui::widgets::{Block, Borders};
use ratatui::Frame;
use crate::audio::engine::{EngineHandle, SCOPE_CAPACITY};
pub fn render(f: &mut Frame, area: Rect, engine: &EngineHandle) {
let samples: Vec<(f32, f32)> = engine.scope.lock().iter().copied().collect();
let len = samples.len().max(1);
let canvas = Canvas::default()
.block(
Block::default()
.borders(Borders::ALL)
.title(" scope ยท L/R ")
.title_style(Style::default().add_modifier(Modifier::BOLD)),
)
.marker(Marker::Braille)
.x_bounds([0.0, SCOPE_CAPACITY as f64])
.y_bounds([-1.2, 1.2])
.paint(move |ctx| {
draw_channel(ctx, &samples, |s| s.0, Color::Cyan, len);
draw_channel(ctx, &samples, |s| s.1, Color::Magenta, len);
ctx.draw(&Line {
x1: 0.0,
y1: 0.0,
x2: SCOPE_CAPACITY as f64,
y2: 0.0,
color: Color::DarkGray,
});
});
f.render_widget(canvas, area);
}
fn draw_channel(
ctx: &mut Context,
samples: &[(f32, f32)],
pick: impl Fn(&(f32, f32)) -> f32,
color: Color,
len: usize,
) {
let n = samples.len();
if n < 2 {
return;
}
let step = SCOPE_CAPACITY as f64 / len as f64;
for i in 1..n {
let x1 = (i - 1) as f64 * step;
let x2 = i as f64 * step;
let y1 = pick(&samples[i - 1]) as f64;
let y2 = pick(&samples[i]) as f64;
ctx.draw(&Line {
x1,
y1: y1.clamp(-1.2, 1.2),
x2,
y2: y2.clamp(-1.2, 1.2),
color,
});
}
}