aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsam-anthony <samanthony6@protonmail.com>2022-01-26 06:37:29 -0330
committersam-anthony <samanthony6@protonmail.com>2022-01-26 06:37:29 -0330
commitb45ddda0fda44ffb5e4ffbfe94b4d293b06d883e (patch)
treeb0167611d285da4302b575ae35f93ee4902eb3dd /src
parenteb55242f08fcd4a9a3fdcc8de1110999614c8813 (diff)
downloadvolute-b45ddda0fda44ffb5e4ffbfe94b4d293b06d883e.zip
basic input handling
Diffstat (limited to 'src')
-rw-r--r--src/flow_rate.rs32
-rw-r--r--src/lib.rs12
-rw-r--r--src/main.rs250
-rw-r--r--src/mass.rs31
-rw-r--r--src/pressure.rs11
-rw-r--r--src/temperature.rs11
-rw-r--r--src/unit_of_measurement.rs107
-rw-r--r--src/volume.rs23
8 files changed, 277 insertions, 200 deletions
diff --git a/src/flow_rate.rs b/src/flow_rate.rs
deleted file mode 100644
index f8e15e0..0000000
--- a/src/flow_rate.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-use crate::{mass::Mass, volume::Volume};
-use std::time::Duration;
-
-pub struct MassFlowRate {
- pub mass: Mass,
- pub duration: Duration,
-}
-
-impl MassFlowRate {
- pub fn as_kilograms_per_minute(&self) -> f64 {
- self.mass.as_kilograms() / (self.duration.as_secs() as f64 / 60.)
- }
-
- pub fn as_pounds_per_minute(&self) -> f64 {
- self.mass.as_pounds() / (self.duration.as_secs() as f64 / 60.)
- }
-}
-
-pub struct VolumetricFlowRate {
- pub volume: Volume,
- pub duration: Duration,
-}
-
-impl VolumetricFlowRate {
- pub fn as_cubic_metres_per_second(&self) -> f64 {
- self.volume.as_cubic_metres() / self.duration.as_secs() as f64
- }
-
- pub fn as_cubic_feet_per_minute(&self) -> f64 {
- self.volume.as_cubic_feet() / (self.duration.as_secs() as f64 / 60.)
- }
-}
diff --git a/src/lib.rs b/src/lib.rs
index 79dda37..8fd6b17 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,14 +1,10 @@
-pub mod flow_rate;
-pub mod mass;
-pub mod pressure;
-pub mod temperature;
-pub mod volume;
+pub mod unit_of_measurement;
-use crate::{pressure::Pressure, temperature::Temperature, volume::Volume};
+use crate::unit_of_measurement::{Pressure, Temperature, Volume};
const GAS_CONSTANT: f64 = 8.314472;
const MOLAR_MASS_OF_AIR: f64 = 0.0289647; // Kg/mol
-fn moles_from_gas_law(pressure: Pressure, volume: Volume, temperature: Temperature) -> f64 {
- (pressure.as_pascals() * volume.as_cubic_metres()) / (GAS_CONSTANT * temperature.as_kelvin())
+fn moles_from_gas_law(pres: Pressure, vol: Volume, temp: Temperature) -> f64 {
+ (pres.as_pascals() * vol.as_cubic_metres()) / (GAS_CONSTANT * temp.as_kelvin())
}
diff --git a/src/main.rs b/src/main.rs
index 98e74c7..fa871ea 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,5 @@
use crossterm::{
- event::{
- self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEvent, KeyModifiers,
- },
+ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
@@ -9,34 +7,108 @@ use std::{error::Error, io};
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Constraint, Direction, Layout},
- style::{Color, Modifier, Style},
- text::{Span, Spans},
- widgets::{Block, Borders, Tabs},
+ style::{Color, Style},
+ widgets::{Block, Borders, Paragraph},
Frame, Terminal,
};
+use unicode_width::UnicodeWidthStr;
-struct App<'a> {
- pub titles: Vec<&'a str>,
- pub index: usize,
+enum InputMode {
+ Normal,
+ Insert,
}
-impl<'a> App<'a> {
- fn new() -> App<'a> {
- App {
- titles: vec!["constants", "compressor", "power"],
- index: 0,
+enum Row {
+ Rpm(String),
+ Ve(String),
+ Map(String),
+}
+
+impl Row {
+ fn push(&mut self, c: char) {
+ match self {
+ Row::Rpm(rpm) => {
+ rpm.push(c);
+ *self = Row::Rpm(rpm.to_string());
+ }
+ Row::Ve(ve) => {
+ ve.push(c);
+ *self = Row::Ve(ve.to_string());
+ }
+ Row::Map(map) => {
+ map.push(c);
+ *self = Row::Map(map.to_string());
+ }
+ }
+ }
+
+ fn pop(&mut self) {
+ match self {
+ Row::Rpm(rpm) => {
+ rpm.pop();
+ *self = Row::Rpm(rpm.to_string());
+ }
+ Row::Ve(ve) => {
+ ve.pop();
+ *self = Row::Rpm(ve.to_string());
+ }
+ Row::Map(map) => {
+ map.pop();
+ *self = Row::Map(map.to_string());
+ }
+ }
+ }
+
+ fn string(&self) -> String {
+ match self {
+ Row::Rpm(rpm) => rpm.to_string(),
+ Row::Ve(ve) => ve.to_string(),
+ Row::Map(map) => map.to_string(),
+ }
+ }
+
+ fn next(&self) -> Self {
+ match self {
+ Row::Rpm(_) => Row::Ve(String::new()),
+ Row::Ve(_) => Row::Map(String::new()),
+ Row::Map(_) => Row::Rpm(String::new()),
}
}
- pub fn next(&mut self) {
- self.index = (self.index + 1) % self.titles.len();
+ fn previous(&self) -> Self {
+ match self {
+ Row::Rpm(_) => Row::Map(String::new()),
+ Row::Ve(_) => Row::Rpm(String::new()),
+ Row::Map(_) => Row::Ve(String::new()),
+ }
}
+}
+
+struct Column {
+ rpm: Row,
+ ve: Row,
+ map: Row,
+}
+
+/// App holds the state of the application
+struct App {
+ column: Column,
+
+ selected_row: Row,
- pub fn previous(&mut self) {
- if self.index > 0 {
- self.index -= 1;
- } else {
- self.index = self.titles.len() - 1;
+ input_mode: InputMode,
+}
+
+impl Default for App {
+ fn default() -> App {
+ App {
+ column: Column {
+ rpm: Row::Rpm(String::from("7000")),
+ ve: Row::Ve(String::from("95")),
+ map: Row::Map(String::from("150")),
+ },
+ selected_row: Row::Rpm(String::new()),
+ input_mode: InputMode::Normal,
}
}
}
@@ -50,7 +122,7 @@ fn main() -> Result<(), Box<dyn Error>> {
let mut terminal = Terminal::new(backend)?;
// create app and run it
- let app = App::new();
+ let app = App::default();
let res = run_app(&mut terminal, app);
// restore terminal
@@ -65,85 +137,95 @@ fn main() -> Result<(), Box<dyn Error>> {
if let Err(err) = res {
println!("{:?}", err)
}
+
Ok(())
}
fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<()> {
loop {
terminal.draw(|f| ui(f, &app))?;
+
if let Event::Key(key) = event::read()? {
- match key {
- KeyEvent {
- modifiers: KeyModifiers::CONTROL,
- code,
- } => match code {
- KeyCode::Char('h') => app.previous(),
- KeyCode::Char('l') => app.next(),
- KeyCode::Char('c') => return Ok(()),
+ match app.input_mode {
+ InputMode::Normal => match key.code {
+ KeyCode::Char('i') => {
+ app.input_mode = InputMode::Insert;
+ }
+ KeyCode::Char('q') => {
+ return Ok(());
+ }
+ KeyCode::Char('j') => {
+ app.selected_row = app.selected_row.next();
+ }
+ KeyCode::Char('k') => {
+ app.selected_row = app.selected_row.previous();
+ }
_ => {}
},
- KeyEvent {
- modifiers: KeyModifiers::NONE,
- code,
- } => match code {
- KeyCode::Char('q') => return Ok(()),
- KeyCode::Esc => return Ok(()),
+ InputMode::Insert => match key.code {
+ KeyCode::Enter => {
+ app.input_mode = InputMode::Normal;
+ }
+ KeyCode::Char(c) => match app.selected_row {
+ Row::Rpm(_) => {
+ app.column.rpm.push(c);
+ }
+ Row::Ve(_) => {
+ app.column.ve.push(c);
+ }
+ Row::Map(_) => {
+ app.column.map.push(c);
+ }
+ },
+ KeyCode::Backspace => match app.selected_row {
+ Row::Rpm(_) => {
+ app.column.rpm.pop();
+ }
+ Row::Ve(_) => {
+ app.column.ve.pop();
+ }
+ Row::Map(_) => {
+ app.column.map.pop();
+ }
+ },
+ KeyCode::Esc => {
+ app.input_mode = InputMode::Normal;
+ }
_ => {}
},
- _ => {}
}
}
}
}
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
- let size = f.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
- .constraints(
- [
- Constraint::Length(3), // tabs
- Constraint::Percentage(45), // inputs
- Constraint::Percentage(45), // graph
- ]
- .as_ref(),
- )
- .split(size);
-
- let block = Block::default().style(Style::default().bg(Color::Black).fg(Color::White));
- f.render_widget(block, size);
- let titles = app
- .titles
- .iter()
- .map(|t| Spans::from(Span::styled(*t, Style::default().fg(Color::Green))))
- .collect();
- let tabs = Tabs::new(titles)
- .block(Block::default().borders(Borders::ALL).title("Tabs"))
- .select(app.index)
- .style(Style::default().fg(Color::Cyan))
- .highlight_style(
- Style::default()
- .add_modifier(Modifier::BOLD)
- .bg(Color::Black),
- );
- f.render_widget(tabs, chunks[0]);
- let (inputs, graph) = match app.index {
- 0 => (
- Block::default().title("Constants").borders(Borders::ALL),
- Block::default(),
- ),
- 1 => (
- Block::default().title("Compressor").borders(Borders::ALL),
- Block::default()
- .title("Compressor Graph")
- .borders(Borders::ALL),
- ),
- 2 => (
- Block::default().title("Power").borders(Borders::ALL),
- Block::default().title("Power Graph").borders(Borders::ALL),
- ),
- _ => unreachable!(),
- };
- f.render_widget(inputs, chunks[1]);
- f.render_widget(graph, chunks[2]);
+ .margin(2)
+ .constraints([Constraint::Length(3), Constraint::Length(3), Constraint::Length(3)].as_ref())
+ .split(f.size());
+
+ let rpm = Paragraph::new(app.column.rpm.string())
+ .style(match app.selected_row {
+ Row::Rpm(_) => Style::default().fg(Color::Yellow),
+ _ => Style::default(),
+ })
+ .block(Block::default().borders(Borders::ALL).title("rpm"));
+ f.render_widget(rpm, chunks[0]);
+
+ let ve = Paragraph::new(app.column.ve.string())
+ .style(match app.selected_row {
+ Row::Ve(_) => Style::default().fg(Color::Yellow),
+ _ => Style::default(),
+ })
+ .block(Block::default().borders(Borders::ALL).title("ve"));
+ f.render_widget(ve, chunks[1]);
+
+ let map = Paragraph::new(app.column.map.string())
+ .style(match app.selected_row {
+ Row::Map(_) => Style::default().fg(Color::Yellow),
+ _ => Style::default(),
+ })
+ .block(Block::default().borders(Borders::ALL).title("map"));
+ f.render_widget(map, chunks[2]);
}
diff --git a/src/mass.rs b/src/mass.rs
deleted file mode 100644
index 9c57f16..0000000
--- a/src/mass.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-pub struct Mass(f64); // Base unit is grams
-
-impl Mass {
- /* constructors */
- pub fn from_grams(grams: f64) -> Mass {
- Mass(grams)
- }
-
- pub fn from_kilograms(kilos: f64) -> Mass {
- Mass(kilos / 1000.)
- }
-
- pub fn from_moles(moles: f64, molar_mass: f64) -> Mass {
- let kilos = moles * molar_mass;
- Mass::from_kilograms(kilos)
- }
-
- /* metric */
- pub fn as_grams(&self) -> f64 {
- self.0
- }
-
- pub fn as_kilograms(&self) -> f64 {
- self.0 / 1000.
- }
-
- /* imperial */
- pub fn as_pounds(&self) -> f64 {
- self.0 * 0.002204623
- }
-}
diff --git a/src/pressure.rs b/src/pressure.rs
deleted file mode 100644
index f746186..0000000
--- a/src/pressure.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub struct Pressure(f64); // Base unit is pascals
-
-impl Pressure {
- pub fn from_pascals(pascals: f64) -> Self {
- Self(pascals)
- }
-
- pub fn as_pascals(&self) -> f64 {
- self.0
- }
-}
diff --git a/src/temperature.rs b/src/temperature.rs
deleted file mode 100644
index 2eac48d..0000000
--- a/src/temperature.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub struct Temperature(f64); // Base unit is kelvin
-
-impl Temperature {
- pub fn from_kelvin(kelvin: f64) -> Temperature {
- Temperature(kelvin)
- }
-
- pub fn as_kelvin(&self) -> f64 {
- self.0
- }
-}
diff --git a/src/unit_of_measurement.rs b/src/unit_of_measurement.rs
new file mode 100644
index 0000000..03bb68c
--- /dev/null
+++ b/src/unit_of_measurement.rs
@@ -0,0 +1,107 @@
+use std::time::Duration;
+
+pub struct MassFlowRate {
+ pub mass: Mass,
+ pub duration: Duration,
+}
+impl MassFlowRate {
+ pub fn as_kilograms_per_minute(&self) -> f64 {
+ self.mass.as_kilograms() / (self.duration.as_secs() as f64 / 60.)
+ }
+
+ pub fn as_pounds_per_minute(&self) -> f64 {
+ self.mass.as_pounds() / (self.duration.as_secs() as f64 / 60.)
+ }
+}
+
+pub struct VolumetricFlowRate {
+ pub volume: Volume,
+ pub duration: Duration,
+}
+impl VolumetricFlowRate {
+ pub fn as_cubic_metres_per_second(&self) -> f64 {
+ self.volume.as_cubic_metres() / self.duration.as_secs() as f64
+ }
+
+ pub fn as_cubic_feet_per_minute(&self) -> f64 {
+ self.volume.as_cubic_feet() / (self.duration.as_secs() as f64 / 60.)
+ }
+}
+
+#[derive(Default)]
+pub struct Mass(f64); // Base unit is grams
+impl Mass {
+ /* constructors */
+ pub fn from_grams(grams: f64) -> Mass {
+ Mass(grams)
+ }
+
+ pub fn from_kilograms(kilos: f64) -> Mass {
+ Mass(kilos / 1000.)
+ }
+
+ pub fn from_moles(moles: f64, molar_mass: f64) -> Mass {
+ let kilos = moles * molar_mass;
+ Mass::from_kilograms(kilos)
+ }
+
+ /* metric */
+ pub fn as_grams(&self) -> f64 {
+ self.0
+ }
+
+ pub fn as_kilograms(&self) -> f64 {
+ self.0 / 1000.
+ }
+
+ /* imperial */
+ pub fn as_pounds(&self) -> f64 {
+ self.0 * 0.002204623
+ }
+}
+
+pub struct Pressure(f64); // Base unit is pascals
+impl Pressure {
+ pub fn from_pascals(pascals: f64) -> Self {
+ Self(pascals)
+ }
+
+ pub fn as_pascals(&self) -> f64 {
+ self.0
+ }
+}
+
+#[derive(Default)]
+pub struct Temperature(f64); // Base unit is kelvin
+impl Temperature {
+ pub fn from_kelvin(kelvin: f64) -> Temperature {
+ Temperature(kelvin)
+ }
+
+ pub fn as_kelvin(&self) -> f64 {
+ self.0
+ }
+}
+
+pub struct Volume(f64); // Base unit is cubic metres
+impl Volume {
+ pub fn from_cubic_metres(cubic_metres: f64) -> Volume {
+ Volume(cubic_metres)
+ }
+
+ pub fn from_cubic_centimetres(cubic_centimetres: f64) -> Volume {
+ Volume(cubic_centimetres / 1_000_000.)
+ }
+
+ pub fn as_cubic_metres(&self) -> f64 {
+ self.0
+ }
+
+ pub fn as_cubic_centimetres(&self) -> f64 {
+ self.0 * 1_000_000.
+ }
+
+ pub fn as_cubic_feet(&self) -> f64 {
+ self.0 * 35.3147
+ }
+}
diff --git a/src/volume.rs b/src/volume.rs
deleted file mode 100644
index d6ef206..0000000
--- a/src/volume.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-pub struct Volume(f64); // Base unit is cubic metres
-
-impl Volume {
- pub fn from_cubic_metres(cubic_metres: f64) -> Volume {
- Volume(cubic_metres)
- }
-
- pub fn from_cubic_centimetres(cubic_centimetres: f64) -> Volume {
- Volume(cubic_centimetres / 1_000_000.)
- }
-
- pub fn as_cubic_metres(&self) -> f64 {
- self.0
- }
-
- pub fn as_cubic_centimetres(&self) -> f64 {
- self.0 * 1_000_000.
- }
-
- pub fn as_cubic_feet(&self) -> f64 {
- self.0 * 35.3147
- }
-}