Browse and listen to thousands of radio stations across the globe right from your terminal ๐ŸŒŽ ๐Ÿ“ป ๐ŸŽตโœจ
radio rust tokio web-radio command-line-tool tui
at main 2.5 kB view raw
1pub mod oscilloscope; 2pub mod spectroscope; 3pub mod vectorscope; 4 5use crossterm::event::Event; 6use ratatui::{ 7 style::{Color, Style}, 8 symbols::Marker, 9 widgets::{Axis, Dataset, GraphType}, 10}; 11 12use crate::input::Matrix; 13 14pub enum Dimension { 15 X, 16 Y, 17} 18 19#[derive(Debug, Clone)] 20pub struct GraphConfig { 21 pub pause: bool, 22 pub samples: u32, 23 #[allow(dead_code)] 24 pub sampling_rate: u32, 25 pub scale: f64, 26 pub width: u32, 27 pub scatter: bool, 28 pub references: bool, 29 pub show_ui: bool, 30 pub marker_type: Marker, 31 pub palette: Vec<Color>, 32 pub labels_color: Color, 33 pub axis_color: Color, 34} 35 36impl GraphConfig { 37 pub fn palette(&self, index: usize) -> Color { 38 *self 39 .palette 40 .get(index % self.palette.len()) 41 .unwrap_or(&Color::White) 42 } 43} 44 45#[allow(clippy::ptr_arg)] 46pub trait DisplayMode { 47 // MUST define 48 fn from_args(args: &crate::cfg::SourceOptions) -> Self 49 where 50 Self: Sized; 51 fn axis(&self, cfg: &GraphConfig, dimension: Dimension) -> Axis<'_>; // TODO simplify this 52 fn process(&mut self, cfg: &GraphConfig, data: &Matrix<f64>) -> Vec<DataSet>; 53 fn mode_str(&self) -> &'static str; 54 55 // SHOULD override 56 fn channel_name(&self, index: usize) -> String { 57 format!("{}", index) 58 } 59 fn header(&self, _cfg: &GraphConfig) -> String { 60 "".into() 61 } 62 fn references(&self, _cfg: &GraphConfig) -> Vec<DataSet> { 63 vec![] 64 } 65 fn handle(&mut self, _event: Event) {} 66} 67 68pub struct DataSet { 69 name: Option<String>, 70 data: Vec<(f64, f64)>, 71 marker_type: Marker, 72 graph_type: GraphType, 73 color: Color, 74} 75 76impl<'a> From<&'a DataSet> for Dataset<'a> { 77 fn from(ds: &'a DataSet) -> Dataset<'a> { 78 let mut out = Dataset::default(); // TODO creating a binding is kinda ugly, is it avoidable? 79 if let Some(name) = &ds.name { 80 out = out.name(name.clone()); 81 } 82 out.marker(ds.marker_type) 83 .graph_type(ds.graph_type) 84 .style(Style::default().fg(ds.color)) 85 .data(&ds.data) 86 } 87} 88 89// TODO this is pretty ugly but I need datasets which own the data 90impl DataSet { 91 pub fn new( 92 name: Option<String>, 93 data: Vec<(f64, f64)>, 94 marker_type: Marker, 95 graph_type: GraphType, 96 color: Color, 97 ) -> Self { 98 DataSet { 99 name, 100 data, 101 marker_type, 102 graph_type, 103 color, 104 } 105 } 106}