use std::cell::RefCell;
use std::rc::Rc;
use saudade::{
App, Container, Event, EventCtx, Label, Painter, Rect, TextInput, Theme, Widget, WindowConfig,
};
const W: i32 = 320;
const H: i32 = 72;
fn main() {
let celsius = Rc::new(RefCell::new(TextInput::new(Rect::new(16, 24, 70, 24))));
let fahrenheit = Rc::new(RefCell::new(TextInput::new(Rect::new(170, 24, 70, 24))));
celsius.borrow_mut().set_on_change({
let fahrenheit = fahrenheit.clone();
move |_cx, text| {
if let Ok(c) = text.trim().parse::<f64>() {
let f = c * 9.0 / 5.0 + 32.0;
fahrenheit.borrow_mut().set_text(&fmt_temp(f));
}
}
});
fahrenheit.borrow_mut().set_on_change({
let celsius = celsius.clone();
move |_cx, text| {
if let Ok(f) = text.trim().parse::<f64>() {
let c = (f - 32.0) * 5.0 / 9.0;
celsius.borrow_mut().set_text(&fmt_temp(c));
}
}
});
let root = Container::new(W, H)
.add(SharedTextInput(celsius.clone()))
.add(Label::new(Rect::new(94, 29, 72, 16), "Celsius ="))
.add(SharedTextInput(fahrenheit.clone()))
.add(Label::new(Rect::new(248, 29, 64, 16), "Fahrenheit"));
App::new(WindowConfig::new("TempConv", W, H), root)
.with_theme(Theme::windows_31())
.run();
}
fn fmt_temp(v: f64) -> String {
let rounded = (v * 10.0).round() / 10.0;
if rounded == rounded.trunc() {
format!("{}", rounded as i64)
} else {
format!("{rounded}")
}
}
struct SharedTextInput(Rc<RefCell<TextInput>>);
impl Widget for SharedTextInput {
fn bounds(&self) -> Rect {
self.0.borrow().bounds()
}
fn paint(&mut self, painter: &mut Painter, theme: &Theme) {
self.0.borrow_mut().paint(painter, theme);
}
fn event(&mut self, event: &Event, ctx: &mut EventCtx) {
self.0.borrow_mut().event(event, ctx);
}
fn captures_pointer(&self) -> bool {
self.0.borrow().captures_pointer()
}
fn focusable(&self) -> bool {
self.0.borrow().focusable()
}
fn set_focused(&mut self, focused: bool) {
self.0.borrow_mut().set_focused(focused);
}
fn layout(&mut self, bounds: Rect) {
self.0.borrow_mut().layout(bounds);
}
fn wants_ticks(&self) -> bool {
self.0.borrow().wants_ticks()
}
}