/* Copyright 2023, Savanni D'Gerinel This file is part of FitnessTrax. FitnessTrax is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FitnessTrax is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FitnessTrax. If not, see . */ use gtk::prelude::*; use std::{cell::RefCell, rc::Rc}; pub struct ParseError; #[derive(Clone)] pub struct TextEntry { value: Rc>>, widget: gtk::Entry, } impl TextEntry { pub fn new( placeholder: &str, value: Option, validator: &'static dyn Fn(&str) -> Result, ) -> Self { let widget = gtk::Entry::builder().placeholder_text(placeholder).build(); let s = Self { value: Rc::new(RefCell::new(value)), widget, }; s.widget.buffer().connect_text_notify({ let s = s.clone(); move |buffer| { if buffer.text().is_empty() { *s.value.borrow_mut() = None; } match validator(buffer.text().as_str()) { Ok(v) => *s.value.borrow_mut() = Some(v), // need to change the border to provide a visual indicator of an error Err(_) => {} } } }); s } pub fn value(&self) -> Option { self.value.borrow().clone() } pub fn set_value(&self, value: Option) { *self.value.borrow_mut() = value; } pub fn grab_focus(&self) { self.widget.grab_focus(); } pub fn widget(&self) -> gtk::Widget { self.widget.clone().upcast::() } }