Start building an internally editable date field
This commit is contained in:
parent
ab59eedef5
commit
b33d17c256
|
@ -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: >k::TextBuffer) {
|
||||||
|
let (start, end) = buffer.bounds();
|
||||||
|
println!("[on_update] {}", buffer.text(&start, &end, true));
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,6 +21,9 @@ pub use action_group::ActionGroup;
|
||||||
mod day;
|
mod day;
|
||||||
pub use day::{DayDetail, DayEdit, DaySummary};
|
pub use day::{DayDetail, DayEdit, DaySummary};
|
||||||
|
|
||||||
|
mod date_field;
|
||||||
|
pub use date_field::DateField;
|
||||||
|
|
||||||
mod singleton;
|
mod singleton;
|
||||||
pub use singleton::{Singleton, SingletonImpl};
|
pub use singleton::{Singleton, SingletonImpl};
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,10 @@ You should have received a copy of the GNU General Public License along with Fit
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App, components::DaySummary, types::DayInterval, view_models::DayDetailViewModel,
|
app::App,
|
||||||
|
components::{DateField, DaySummary},
|
||||||
|
types::DayInterval,
|
||||||
|
view_models::DayDetailViewModel,
|
||||||
};
|
};
|
||||||
|
|
||||||
use glib::Object;
|
use glib::Object;
|
||||||
|
@ -106,6 +109,22 @@ impl HistoricalView {
|
||||||
|
|
||||||
*s.imp().app.borrow_mut() = Some(app);
|
*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(>k::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(>k::Button::builder().label("last week").build());
|
||||||
|
quick_picker.append(>k::Button::builder().label("last two weeks").build());
|
||||||
|
quick_picker.append(>k::Button::builder().label("last month").build());
|
||||||
|
quick_picker.append(>k::Button::builder().label("last six months").build());
|
||||||
|
quick_picker.append(>k::Button::builder().label("last year").build());
|
||||||
|
|
||||||
let mut model = gio::ListStore::new::<Date>();
|
let mut model = gio::ListStore::new::<Date>();
|
||||||
model.extend(interval.days().map(Date::new));
|
model.extend(interval.days().map(Date::new));
|
||||||
s.imp()
|
s.imp()
|
||||||
|
@ -122,6 +141,8 @@ impl HistoricalView {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
s.append(&date_row);
|
||||||
|
s.append(&quick_picker);
|
||||||
s.append(&s.imp().list_view);
|
s.append(&s.imp().list_view);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
|
Loading…
Reference in New Issue