use iced::{ widget::{column, pick_list, row, text, text_input}, Element, Sandbox, Settings, }; use volute::{ round, volume::{self, CubicMetre}, }; const DECIMAL_DIGITS: i8 = 4; pub fn main() -> iced::Result { App::run(Settings::default()) } #[derive(Default)] struct App { displacement: CubicMetre, ui: UI, } #[derive(Default)] struct UI { displacement: String, displacement_unit: volume::Unit, } impl App { fn set_displacement(&mut self, displacement: &str) { if displacement.len() == 0 { self.displacement.0 = 0.0; self.ui.displacement = "".to_string(); } else if let Ok(val) = displacement.parse::() { self.displacement = CubicMetre::from_unit(self.ui.displacement_unit, val); self.ui.displacement = String::from(displacement); } } } impl UI { fn convert_displacement(&mut self, unit: volume::Unit) { if self.displacement.len() > 0 { self.displacement = format!( "{}", round( volume::convert( self.displacement.parse::().unwrap(), self.displacement_unit, unit, ), DECIMAL_DIGITS, ), ); } self.displacement_unit = unit; } } impl Sandbox for App { type Message = Message; fn new() -> Self { Self::default() } fn title(&self) -> String { String::from("volute") } fn update(&mut self, message: Message) { match message { Message::Displacement(displacement) => { self.set_displacement(&displacement); } Message::DisplacementUnit(unit) => { self.ui.convert_displacement(unit); } } } fn view(&self) -> Element { column![row![ text("Displacement:"), text_input("2.0", &self.ui.displacement, Message::Displacement), pick_list( &volume::Unit::ALL[..], Some(self.ui.displacement_unit), Message::DisplacementUnit, ), ]] .into() } } #[derive(Debug, Clone)] pub enum Message { Displacement(String), DisplacementUnit(volume::Unit), }