monorepo/fitnesstrax/app/src/components/date_field.rs

114 lines
3.1 KiB
Rust
Raw Normal View History

/*
Copyright 2024, Savanni D'Gerinel <savanni@luminescent-dreams.com>
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 <https://www.gnu.org/licenses/>.
*/
2024-02-15 14:11:34 +00:00
use crate::{components::TextEntry, types::ParseError};
use chrono::{Datelike, Local};
use glib::Object;
use gtk::{prelude::*, subclass::prelude::*};
use std::{cell::RefCell, rc::Rc};
2024-02-15 14:11:34 +00:00
#[derive(Clone, Debug)]
enum Part {
Year,
Month,
Day,
}
pub struct DateFieldPrivate {
value: Rc<RefCell<chrono::NaiveDate>>,
2024-02-15 14:11:34 +00:00
year: TextEntry<i32>,
month: TextEntry<u32>,
day: TextEntry<u32>,
}
#[glib::object_subclass]
impl ObjectSubclass for DateFieldPrivate {
const NAME: &'static str = "DateField";
type Type = DateField;
type ParentType = gtk::Box;
fn new() -> Self {
let date = Local::now().date_naive();
let year = TextEntry::new(
"year",
Some(date.year()),
|v| format!("{}", v),
|v| v.parse::<i32>().map_err(|_| ParseError),
|_| {},
);
let month = TextEntry::new(
"month",
Some(date.month()),
|v| format!("{}", v),
|v| v.parse::<u32>().map_err(|_| ParseError),
|_| {},
);
let day = TextEntry::new(
"day",
Some(date.day()),
|v| format!("{}", v),
|v| v.parse::<u32>().map_err(|_| ParseError),
|_| {},
);
Self {
value: Rc::new(RefCell::new(date.clone())),
year,
month,
day,
}
}
}
2024-02-15 14:11:34 +00:00
impl ObjectImpl for DateFieldPrivate {}
impl WidgetImpl for DateFieldPrivate {}
impl BoxImpl for DateFieldPrivate {}
glib::wrapper! {
pub struct DateField(ObjectSubclass<DateFieldPrivate>) @extends gtk::Box, gtk::Widget;
}
/* Render a date in the format 2006 Jan 01. The entire date is editable. When the user moves to one part of the date, it will be erased and replaced with a grey placeholder.
*/
impl DateField {
pub fn new(date: chrono::NaiveDate) -> Self {
2024-02-15 14:11:34 +00:00
let s: Self = Object::builder().build();
println!("{}", date);
2024-02-15 14:11:34 +00:00
s.append(&s.imp().year.widget());
s.append(&s.imp().month.widget());
s.append(&s.imp().day.widget());
s.imp().year.set_value(Some(date.year()));
s.imp().month.set_value(Some(date.month()));
s.imp().day.set_value(Some(date.day()));
*s.imp().value.borrow_mut() = date;
s
}
2024-02-15 14:11:34 +00:00
}
2024-02-15 14:11:34 +00:00
/* As soon as the field gets focus, highlight the first element
*/
2024-02-15 14:11:34 +00:00
#[cfg(test)]
mod test {
use super::*;
use crate::gtk_init::gtk_init;
}