Start building an internally editable date field

This commit is contained in:
Savanni D'Gerinel 2024-02-10 11:38:25 -05:00
parent 5a93c4fdcd
commit e87b332705
3 changed files with 100 additions and 1 deletions

View File

@ -0,0 +1,75 @@
/*
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/>.
*/
use crate::types::ParseError;
use chrono::Datelike;
use gtk::prelude::*;
use std::{cell::RefCell, rc::Rc};
#[derive(Clone)]
pub struct DateField {
value: Rc<RefCell<chrono::NaiveDate>>,
buffer: gtk::TextBuffer,
widget: gtk::TextView,
}
impl DateField {
pub fn new(date: chrono::NaiveDate) -> Self {
let buffer = gtk::TextBuffer::new(None);
let tag = buffer.create_tag(
Some("placeholder"),
&[("foreground", &String::from("grey"))],
);
buffer.set_text("regular text placeholder text");
let (start, end) = buffer.bounds();
let mut placeholder_start = start.clone();
placeholder_start.forward_chars(13);
let placeholder_markup = buffer.tag_table().lookup("placeholder").unwrap();
buffer.apply_tag(&placeholder_markup, &placeholder_start, &end);
let widget = gtk::TextView::builder()
.buffer(&buffer)
.editable(true)
.can_focus(true)
.height_request(50)
.width_request(200)
.build();
let s = Self {
value: Rc::new(RefCell::new(date)),
buffer,
widget,
};
s.widget.buffer().connect_text_notify({
let s = s.clone();
move |buffer| s.on_update(buffer)
});
s
}
pub fn widget(&self) -> gtk::Widget {
self.widget.clone().upcast::<gtk::Widget>()
}
fn on_update(&self, buffer: &gtk::TextBuffer) {
let (start, end) = buffer.bounds();
println!("[on_update] {}", buffer.text(&start, &end, true));
}
}

View File

@ -21,6 +21,9 @@ pub use action_group::ActionGroup;
mod day;
pub use day::{DayDetail, DayEdit, DaySummary};
mod date_field;
pub use date_field::DateField;
mod singleton;
pub use singleton::{Singleton, SingletonImpl};

View File

@ -15,7 +15,10 @@ You should have received a copy of the GNU General Public License along with Fit
*/
use crate::{
app::App, components::DaySummary, types::DayInterval, view_models::DayDetailViewModel,
app::App,
components::{DateField, DaySummary},
types::DayInterval,
view_models::DayDetailViewModel,
};
use glib::Object;
@ -106,6 +109,22 @@ impl HistoricalView {
*s.imp().app.borrow_mut() = Some(app);
let date_row = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.build();
date_row.append(&DateField::new(interval.start).widget());
date_row.append(&gtk::Label::new(Some("to")));
date_row.append(&DateField::new(interval.end).widget());
let quick_picker = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
.build();
quick_picker.append(&gtk::Button::builder().label("last week").build());
quick_picker.append(&gtk::Button::builder().label("last two weeks").build());
quick_picker.append(&gtk::Button::builder().label("last month").build());
quick_picker.append(&gtk::Button::builder().label("last six months").build());
quick_picker.append(&gtk::Button::builder().label("last year").build());
let mut model = gio::ListStore::new::<Date>();
model.extend(interval.days().map(Date::new));
s.imp()
@ -122,6 +141,8 @@ impl HistoricalView {
}
});
s.append(&date_row);
s.append(&quick_picker);
s.append(&s.imp().list_view);
s