2022-12-24 06:21:58 +01:00
|
|
|
use tui::{style::Color, widgets::GraphType, symbols};
|
|
|
|
|
|
|
|
// use crate::parser::SampleParser;
|
|
|
|
|
2022-12-26 03:12:20 +01:00
|
|
|
pub enum Dimension {
|
2022-12-24 06:21:58 +01:00
|
|
|
X, Y
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
pub struct ChartNames {
|
|
|
|
x: String,
|
|
|
|
y: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct ChartBounds {
|
|
|
|
x: [f64;2],
|
|
|
|
y: [f64;2],
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ChartBounds {
|
|
|
|
fn default() -> Self {
|
|
|
|
ChartBounds { x: [0.0, 0.0], y: [0.0, 0.0] }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
pub struct ChartReferences {
|
|
|
|
pub x: Vec<(f64, f64)>,
|
|
|
|
pub y: Vec<(f64, f64)>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for ChartReferences {
|
|
|
|
fn default() -> Self {
|
|
|
|
ChartReferences {
|
|
|
|
x: vec![(0.0, 0.0), (0.0, 1.0)],
|
|
|
|
y: vec![(0.5, 1.0), (0.5, -1.0)]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-24 06:21:58 +01:00
|
|
|
pub struct AppConfig {
|
|
|
|
pub title: String,
|
|
|
|
pub axis_color: Color,
|
2022-12-27 19:01:48 +01:00
|
|
|
pub palette: Vec<Color>,
|
2022-12-24 06:21:58 +01:00
|
|
|
|
|
|
|
scale: u32,
|
|
|
|
width: u32,
|
|
|
|
vectorscope: bool,
|
|
|
|
pub references: bool,
|
2022-12-27 19:03:11 +01:00
|
|
|
pub triggering: bool,
|
2022-12-24 06:21:58 +01:00
|
|
|
|
|
|
|
pub marker_type: symbols::Marker,
|
2022-12-26 02:18:24 +01:00
|
|
|
pub graph_type: GraphType,
|
|
|
|
}
|
2022-12-24 06:21:58 +01:00
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
pub struct App {
|
|
|
|
pub cfg: AppConfig,
|
|
|
|
pub references: ChartReferences,
|
2022-12-24 06:21:58 +01:00
|
|
|
bounds: ChartBounds,
|
|
|
|
names: ChartNames,
|
|
|
|
}
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
impl App {
|
2022-12-24 06:21:58 +01:00
|
|
|
fn update_values(&mut self) {
|
2022-12-26 02:18:24 +01:00
|
|
|
if self.cfg.vectorscope {
|
2022-12-26 03:12:20 +01:00
|
|
|
self.names.x = "left -".into();
|
2022-12-24 06:21:58 +01:00
|
|
|
self.names.y = "| right".into();
|
2022-12-26 02:18:24 +01:00
|
|
|
self.bounds.x = [-(self.cfg.scale as f64), self.cfg.scale as f64];
|
|
|
|
self.bounds.y = [-(self.cfg.scale as f64), self.cfg.scale as f64];
|
|
|
|
self.references.x = vec![(-(self.cfg.scale as f64), 0.0), (self.cfg.scale as f64, 0.0)];
|
|
|
|
self.references.y = vec![(0.0, -(self.cfg.scale as f64)), (0.0, self.cfg.scale as f64)];
|
2022-12-24 06:21:58 +01:00
|
|
|
} else {
|
2022-12-26 03:12:20 +01:00
|
|
|
self.names.x = "time -".into();
|
2022-12-24 06:21:58 +01:00
|
|
|
self.names.y = "| amplitude".into();
|
2022-12-26 02:18:24 +01:00
|
|
|
self.bounds.x = [0.0, self.cfg.width as f64];
|
|
|
|
self.bounds.y = [-(self.cfg.scale as f64), self.cfg.scale as f64];
|
|
|
|
self.references.x = vec![(0.0, 0.0), (self.cfg.width as f64, 0.0)];
|
|
|
|
let half_width = self.cfg.width as f64 / 2.0;
|
|
|
|
self.references.y = vec![(half_width, -(self.cfg.scale as f64)), (half_width, self.cfg.scale as f64)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 03:12:20 +01:00
|
|
|
pub fn bounds(&self, axis: &Dimension) -> [f64;2] {
|
2022-12-26 02:18:24 +01:00
|
|
|
match axis {
|
2022-12-26 03:12:20 +01:00
|
|
|
Dimension::X => self.bounds.x,
|
|
|
|
Dimension::Y => self.bounds.y,
|
2022-12-26 02:18:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 03:12:20 +01:00
|
|
|
pub fn name(&self, axis: &Dimension) -> &str {
|
2022-12-26 02:18:24 +01:00
|
|
|
match axis {
|
2022-12-26 03:12:20 +01:00
|
|
|
Dimension::X => self.names.x.as_str(),
|
|
|
|
Dimension::Y => self.names.y.as_str(),
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn vectorscope(&self) -> bool {
|
2022-12-26 02:18:24 +01:00
|
|
|
self.cfg.vectorscope
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn scale(&self) -> u32 {
|
2022-12-26 02:18:24 +01:00
|
|
|
self.cfg.scale
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn width(&self) -> u32 {
|
2022-12-26 02:18:24 +01:00
|
|
|
self.cfg.width
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn scatter(&self) -> bool {
|
2022-12-26 02:18:24 +01:00
|
|
|
match self.cfg.graph_type {
|
2022-12-24 06:21:58 +01:00
|
|
|
GraphType::Scatter => true,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
// pub fn references(&self) -> Vec<Dataset> {
|
|
|
|
// vec![
|
|
|
|
// Dataset::default()
|
|
|
|
// .name("")
|
|
|
|
// .marker(self.cfg.marker_type)
|
|
|
|
// .graph_type(GraphType::Line)
|
|
|
|
// .style(Style::default().fg(self.cfg.axis_color))
|
|
|
|
// .data(&self.references.x),
|
|
|
|
// Dataset::default()
|
|
|
|
// .name("")
|
|
|
|
// .marker(self.cfg.marker_type)
|
|
|
|
// .graph_type(GraphType::Line)
|
|
|
|
// .style(Style::default().fg(self.cfg.axis_color))
|
|
|
|
// .data(&self.references.y),
|
|
|
|
// ]
|
|
|
|
// }
|
2022-12-24 06:21:58 +01:00
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
pub fn graph_type(&self) -> GraphType {
|
|
|
|
self.cfg.graph_type
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_vectorscope(&mut self, vectorscope: bool) {
|
2022-12-26 02:18:24 +01:00
|
|
|
self.cfg.vectorscope = vectorscope;
|
2022-12-24 06:21:58 +01:00
|
|
|
self.update_values();
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn update_scale(&mut self, increment: i32) {
|
2022-12-26 02:18:24 +01:00
|
|
|
if increment > 0 || increment.abs() < self.cfg.scale as i32 {
|
|
|
|
self.cfg.scale = ((self.cfg.scale as i32) + increment) as u32;
|
2022-12-24 06:57:56 +01:00
|
|
|
self.update_values();
|
|
|
|
}
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_scatter(&mut self, scatter: bool) {
|
2022-12-26 02:18:24 +01:00
|
|
|
self.cfg.graph_type = if scatter { GraphType::Scatter } else { GraphType::Line };
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
impl From::<&crate::Args> for App {
|
2022-12-24 06:57:56 +01:00
|
|
|
fn from(args: &crate::Args) -> Self {
|
2022-12-24 06:21:58 +01:00
|
|
|
let marker_type = if args.no_braille { symbols::Marker::Dot } else { symbols::Marker::Braille };
|
|
|
|
let graph_type = if args.scatter { GraphType::Scatter } else { GraphType::Line };
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
let cfg = AppConfig {
|
2022-12-24 06:21:58 +01:00
|
|
|
title: "TUI Oscilloscope -- <me@alemi.dev>".into(),
|
|
|
|
axis_color: Color::DarkGray,
|
2022-12-27 19:01:48 +01:00
|
|
|
palette: vec![Color::Red, Color::Yellow],
|
2022-12-24 06:57:56 +01:00
|
|
|
scale: args.range,
|
|
|
|
width: args.buffer / 4, // TODO It's 4 because 2 channels and 2 bytes per sample!
|
2022-12-27 19:03:11 +01:00
|
|
|
triggering: args.triggering,
|
2022-12-24 06:21:58 +01:00
|
|
|
vectorscope: args.vectorscope,
|
|
|
|
references: !args.no_reference,
|
2022-12-26 02:18:24 +01:00
|
|
|
marker_type, graph_type,
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut app = App {
|
|
|
|
cfg,
|
|
|
|
references: ChartReferences::default(),
|
2022-12-24 06:21:58 +01:00
|
|
|
bounds: ChartBounds::default(),
|
|
|
|
names: ChartNames::default(),
|
|
|
|
};
|
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
app.update_values();
|
2022-12-24 06:21:58 +01:00
|
|
|
|
2022-12-26 02:18:24 +01:00
|
|
|
app
|
2022-12-24 06:21:58 +01:00
|
|
|
}
|
|
|
|
}
|