mirror of
https://github.com/alemidev/scope-tui.git
synced 2024-11-23 14:14:48 +01:00
chore: moved config in another file with pub field
This commit is contained in:
parent
15c0ee6a6f
commit
72a7b55c7f
3 changed files with 89 additions and 85 deletions
92
src/app.rs
92
src/app.rs
|
@ -1,67 +1,31 @@
|
||||||
use tui::{style::Color, widgets::GraphType, symbols};
|
|
||||||
|
|
||||||
// use crate::parser::SampleParser;
|
use std::{io::{self, ErrorKind}, time::{Duration, Instant}};
|
||||||
|
use tui::{
|
||||||
|
style::Color, widgets::GraphType, symbols,
|
||||||
|
backend::Backend,
|
||||||
|
widgets::{Block, Chart, Axis, Dataset},
|
||||||
|
Terminal, text::Span, style::{Style, Modifier}, layout::Alignment
|
||||||
|
};
|
||||||
|
use crossterm::event::{self, Event, KeyCode, KeyModifiers};
|
||||||
|
|
||||||
pub enum Dimension {
|
use libpulse_simple_binding::Simple;
|
||||||
X, Y
|
use libpulse_binding::{stream::Direction, def::BufferAttr};
|
||||||
}
|
use libpulse_binding::sample::{Spec, Format};
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct ChartNames {
|
|
||||||
x: String,
|
|
||||||
y: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct ChartBounds {
|
use crate::Args;
|
||||||
x: [f64;2],
|
use crate::config::{ChartNames, ChartBounds, ChartReferences, AppConfig, Dimension};
|
||||||
y: [f64;2],
|
use crate::parser::{SampleParser, Signed16PCM};
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ChartBounds {
|
|
||||||
fn default() -> Self {
|
|
||||||
ChartBounds { x: [0.0, 0.0], y: [0.0, 0.0] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AppConfig {
|
|
||||||
pub title: String,
|
|
||||||
pub axis_color: Color,
|
|
||||||
pub palette: Vec<Color>,
|
|
||||||
|
|
||||||
scale: u32,
|
|
||||||
width: u32,
|
|
||||||
vectorscope: bool,
|
|
||||||
pub references: bool,
|
|
||||||
pub triggering: bool,
|
|
||||||
|
|
||||||
pub marker_type: symbols::Marker,
|
|
||||||
pub graph_type: GraphType,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
pub cfg: AppConfig,
|
pub cfg: AppConfig,
|
||||||
pub references: ChartReferences,
|
pub references: ChartReferences,
|
||||||
bounds: ChartBounds,
|
pub bounds: ChartBounds,
|
||||||
names: ChartNames,
|
pub names: ChartNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn update_values(&mut self) {
|
pub fn update_values(&mut self) {
|
||||||
if self.cfg.vectorscope {
|
if self.cfg.vectorscope {
|
||||||
self.names.x = "left -".into();
|
self.names.x = "left -".into();
|
||||||
self.names.y = "| right".into();
|
self.names.y = "| right".into();
|
||||||
|
@ -94,18 +58,6 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vectorscope(&self) -> bool {
|
|
||||||
self.cfg.vectorscope
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scale(&self) -> u32 {
|
|
||||||
self.cfg.scale
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn width(&self) -> u32 {
|
|
||||||
self.cfg.width
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scatter(&self) -> bool {
|
pub fn scatter(&self) -> bool {
|
||||||
match self.cfg.graph_type {
|
match self.cfg.graph_type {
|
||||||
GraphType::Scatter => true,
|
GraphType::Scatter => true,
|
||||||
|
@ -130,15 +82,6 @@ impl App {
|
||||||
// ]
|
// ]
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn graph_type(&self) -> GraphType {
|
|
||||||
self.cfg.graph_type
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_vectorscope(&mut self, vectorscope: bool) {
|
|
||||||
self.cfg.vectorscope = vectorscope;
|
|
||||||
self.update_values();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_scale(&mut self, increment: i32) {
|
pub fn update_scale(&mut self, increment: i32) {
|
||||||
if increment > 0 || increment.abs() < self.cfg.scale as i32 {
|
if increment > 0 || increment.abs() < self.cfg.scale as i32 {
|
||||||
self.cfg.scale = ((self.cfg.scale as i32) + increment) as u32;
|
self.cfg.scale = ((self.cfg.scale as i32) + increment) as u32;
|
||||||
|
@ -163,6 +106,7 @@ impl From::<&crate::Args> for App {
|
||||||
scale: args.range,
|
scale: args.range,
|
||||||
width: args.buffer / 4, // TODO It's 4 because 2 channels and 2 bytes per sample!
|
width: args.buffer / 4, // TODO It's 4 because 2 channels and 2 bytes per sample!
|
||||||
triggering: args.triggering,
|
triggering: args.triggering,
|
||||||
|
threshold: args.threshold,
|
||||||
vectorscope: args.vectorscope,
|
vectorscope: args.vectorscope,
|
||||||
references: !args.no_reference,
|
references: !args.no_reference,
|
||||||
marker_type, graph_type,
|
marker_type, graph_type,
|
||||||
|
|
56
src/config.rs
Normal file
56
src/config.rs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
use tui::{style::Color, widgets::GraphType, symbols};
|
||||||
|
|
||||||
|
// use crate::parser::SampleParser;
|
||||||
|
|
||||||
|
pub enum Dimension {
|
||||||
|
X, Y
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ChartNames {
|
||||||
|
pub x: String,
|
||||||
|
pub y: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct ChartBounds {
|
||||||
|
pub x: [f64;2],
|
||||||
|
pub y: [f64;2],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChartBounds {
|
||||||
|
fn default() -> Self {
|
||||||
|
ChartBounds { x: [0.0, 0.0], y: [0.0, 0.0] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AppConfig {
|
||||||
|
pub title: String,
|
||||||
|
pub axis_color: Color,
|
||||||
|
pub palette: Vec<Color>,
|
||||||
|
|
||||||
|
pub scale: u32,
|
||||||
|
pub width: u32,
|
||||||
|
pub vectorscope: bool,
|
||||||
|
pub references: bool,
|
||||||
|
|
||||||
|
pub triggering: bool,
|
||||||
|
pub threshold: f64,
|
||||||
|
|
||||||
|
pub marker_type: symbols::Marker,
|
||||||
|
pub graph_type: GraphType,
|
||||||
|
}
|
26
src/main.rs
26
src/main.rs
|
@ -1,5 +1,6 @@
|
||||||
mod parser;
|
mod parser;
|
||||||
mod app;
|
mod app;
|
||||||
|
mod config;
|
||||||
mod music;
|
mod music;
|
||||||
|
|
||||||
use std::{io::{self, ErrorKind}, time::{Duration, Instant}};
|
use std::{io::{self, ErrorKind}, time::{Duration, Instant}};
|
||||||
|
@ -25,6 +26,7 @@ use parser::{SampleParser, Signed16PCM};
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::music::Note;
|
use crate::music::Note;
|
||||||
|
use crate::config::Dimension;
|
||||||
|
|
||||||
/// A simple oscilloscope/vectorscope for your terminal
|
/// A simple oscilloscope/vectorscope for your terminal
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
|
@ -194,16 +196,17 @@ fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io
|
||||||
|
|
||||||
let mut measures;
|
let mut measures;
|
||||||
|
|
||||||
if app.vectorscope() {
|
if app.cfg.vectorscope {
|
||||||
measures = vec![];
|
measures = vec![];
|
||||||
for chunk in channels.chunks(2) {
|
for chunk in channels.chunks(2) {
|
||||||
let mut tmp = vec![];
|
let mut tmp = vec![];
|
||||||
for i in 0..chunk[0].len() {
|
for i in 0..chunk[0].len() {
|
||||||
tmp.push((chunk[0][i] as f64, chunk[1][i] as f64));
|
tmp.push((chunk[0][i] as f64, chunk[1][i] as f64));
|
||||||
}
|
}
|
||||||
|
// split it in two so the math downwards still works the same
|
||||||
let pivot = tmp.len() / 2;
|
let pivot = tmp.len() / 2;
|
||||||
|
measures.push(tmp[pivot..].to_vec()); // put more recent first
|
||||||
measures.push(tmp[..pivot].to_vec());
|
measures.push(tmp[..pivot].to_vec());
|
||||||
measures.push(tmp[pivot..].to_vec());
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
measures = vec![vec![]; channels.len()];
|
measures = vec![vec![]; channels.len()];
|
||||||
|
@ -221,11 +224,11 @@ fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io
|
||||||
datasets.push(data_set("", &app.references.y, app.cfg.marker_type, GraphType::Line, app.cfg.axis_color));
|
datasets.push(data_set("", &app.references.y, app.cfg.marker_type, GraphType::Line, app.cfg.axis_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
let ds_names = if app.vectorscope() { vec!["2", "1"] } else { vec!["R", "L"] };
|
let ds_names = if app.cfg.vectorscope { vec!["1", "2"] } else { vec!["R", "L"] };
|
||||||
let palette : Vec<Color> = app.cfg.palette.iter().rev().map(|x| x.clone()).collect();
|
let palette : Vec<Color> = app.cfg.palette.iter().rev().map(|x| x.clone()).collect();
|
||||||
|
|
||||||
for (i, ds) in measures.iter().rev().enumerate() {
|
for (i, ds) in measures.iter().rev().enumerate() {
|
||||||
datasets.push(data_set(ds_names[i], ds, app.cfg.marker_type, app.graph_type(), palette[i % palette.len()]));
|
datasets.push(data_set(ds_names[i], ds, app.cfg.marker_type, app.cfg.graph_type, palette[i % palette.len()]));
|
||||||
}
|
}
|
||||||
|
|
||||||
fps += 1;
|
fps += 1;
|
||||||
|
@ -240,8 +243,8 @@ fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io
|
||||||
let size = f.size();
|
let size = f.size();
|
||||||
let chart = Chart::new(datasets)
|
let chart = Chart::new(datasets)
|
||||||
.block(block(&app, args.sample_rate as f32, framerate))
|
.block(block(&app, args.sample_rate as f32, framerate))
|
||||||
.x_axis(axis(&app, app::Dimension::X)) // TODO allow to have axis sometimes?
|
.x_axis(axis(&app, Dimension::X)) // TODO allow to have axis sometimes?
|
||||||
.y_axis(axis(&app, app::Dimension::Y));
|
.y_axis(axis(&app, Dimension::Y));
|
||||||
f.render_widget(chart, size)
|
f.render_widget(chart, size)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -261,8 +264,8 @@ fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io
|
||||||
KeyCode::Char('-') => app.update_scale(1000),
|
KeyCode::Char('-') => app.update_scale(1000),
|
||||||
KeyCode::Char('+') => app.update_scale(-100),
|
KeyCode::Char('+') => app.update_scale(-100),
|
||||||
KeyCode::Char('_') => app.update_scale(100),
|
KeyCode::Char('_') => app.update_scale(100),
|
||||||
KeyCode::Char('v') => app.set_vectorscope(!app.vectorscope()),
|
KeyCode::Char('v') => app.cfg.vectorscope = !app.cfg.vectorscope,
|
||||||
KeyCode::Char('s') => app.set_scatter(!app.scatter()),
|
KeyCode::Char('s') => app.set_scatter(!app.scatter()), // TODO no funcs
|
||||||
KeyCode::Char('h') => app.cfg.references = !app.cfg.references,
|
KeyCode::Char('h') => app.cfg.references = !app.cfg.references,
|
||||||
KeyCode::Char('t') => app.cfg.triggering = !app.cfg.triggering,
|
KeyCode::Char('t') => app.cfg.triggering = !app.cfg.triggering,
|
||||||
KeyCode::Up => {},
|
KeyCode::Up => {},
|
||||||
|
@ -271,6 +274,7 @@ fn run_app<T : Backend>(args: Args, terminal: &mut Terminal<T>) -> Result<(), io
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
app.update_values();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +307,7 @@ fn data_set<'a>(
|
||||||
.data(&data)
|
.data(&data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn axis(app: &App, dim: app::Dimension) -> Axis {
|
fn axis(app: &App, dim: Dimension) -> Axis {
|
||||||
let mut a = Axis::default();
|
let mut a = Axis::default();
|
||||||
if app.cfg.references {
|
if app.cfg.references {
|
||||||
a = a.title(Span::styled(app.name(&dim), Style::default().fg(Color::Cyan)));
|
a = a.title(Span::styled(app.name(&dim), Style::default().fg(Color::Cyan)));
|
||||||
|
@ -320,10 +324,10 @@ fn block(app: &App, sample_rate: f32, framerate: u32) -> Block {
|
||||||
Span::styled(
|
Span::styled(
|
||||||
format!(
|
format!(
|
||||||
"TUI {} -- {}{} mode -- range {} -- {} samples -- {:.1} kHz -- {} fps",
|
"TUI {} -- {}{} mode -- range {} -- {} samples -- {:.1} kHz -- {} fps",
|
||||||
if app.vectorscope() { "Vectorscope" } else { "Oscilloscope" },
|
if app.cfg.vectorscope { "Vectorscope" } else { "Oscilloscope" },
|
||||||
if app.cfg.triggering { "triggered " } else { "" },
|
if app.cfg.triggering { "triggered " } else { "" },
|
||||||
if app.scatter() { "scatter" } else { "line" },
|
if app.scatter() { "scatter" } else { "line" },
|
||||||
app.scale(), app.width(), sample_rate / 1000.0, framerate,
|
app.cfg.scale, app.cfg.width, sample_rate / 1000.0, framerate,
|
||||||
),
|
),
|
||||||
Style::default().add_modifier(Modifier::BOLD).fg(Color::Yellow))
|
Style::default().add_modifier(Modifier::BOLD).fg(Color::Yellow))
|
||||||
).title_alignment(Alignment::Center);
|
).title_alignment(Alignment::Center);
|
||||||
|
|
Loading…
Reference in a new issue