Create a swappable UI component #160

Merged
savanni merged 7 commits from fitnesstrax/swappable into main 2024-01-18 12:56:56 +00:00
3 changed files with 24 additions and 6 deletions
Showing only changes of commit 56d0a53666 - Show all commits

View File

@ -309,11 +309,11 @@ impl DayEdit {
_ => None,
});
let weight_view = match weight_record {
Some((_id, data)) => WeightEdit::new(Some(data.clone())),
None => WeightEdit::new(None),
match weight_record {
Some((_id, data)) => s.imp().weight.set_value(Some(data.weight)),
None => s.imp().weight.set_value(None),
};
s.append(&weight_view.widget());
s.append(&s.imp().weight.widget());
s
}

View File

@ -20,15 +20,25 @@ use std::{cell::RefCell, rc::Rc};
pub struct ParseError;
#[derive(Clone)]
pub struct TextEntry<T: Clone> {
pub struct TextEntry<T: Clone + std::fmt::Debug> {
value: Rc<RefCell<Option<T>>>,
widget: gtk::Entry,
renderer: Rc<Box<dyn Fn(&T) -> String>>,
parser: Rc<Box<dyn Fn(&str) -> Result<T, ParseError>>>,
}
impl<T: Clone + std::fmt::Debug> std::fmt::Debug for TextEntry<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"{{ value: {:?}, widget: {:?} }}",
self.value, self.widget
)
}
}
// I do not understand why the data should be 'static.
impl<T: Clone + 'static> TextEntry<T> {
impl<T: Clone + std::fmt::Debug + 'static> TextEntry<T> {
pub fn new<R, V>(placeholder: &str, value: Option<T>, renderer: R, parser: V) -> Self
where
R: Fn(&T) -> String + 'static,
@ -63,6 +73,7 @@ impl<T: Clone + 'static> TextEntry<T> {
}
match (self.parser)(buffer.text().as_str()) {
Ok(v) => {
println!("setting the value: {}", (self.renderer)(&v));
*self.value.borrow_mut() = Some(v);
self.widget.remove_css_class("error");
}
@ -74,6 +85,8 @@ impl<T: Clone + 'static> TextEntry<T> {
}
pub fn value(&self) -> Option<T> {
let v = self.value.borrow().clone();
println!("retrieving the value: {:?}", v.map(|v| (self.renderer)(&v)));
self.value.borrow().clone()
}

View File

@ -48,6 +48,7 @@ impl Weight {
}
}
#[derive(Debug)]
pub struct WeightEdit {
entry: TextEntry<si::Kilogram<f64>>,
}
@ -64,6 +65,10 @@ impl WeightEdit {
}
}
pub fn set_value(&self, value: Option<si::Kilogram<f64>>) {
self.entry.set_value(value);
}
pub fn value(&self) -> Option<si::Kilogram<f64>> {
self.entry.value()
}